Skip to content

Commit

Permalink
PER-9960 Clicking on tag should search the result
Browse files Browse the repository at this point in the history
Created a new route for clicking on tag. This way I can handle the tag scenario in the public search results component
  • Loading branch information
crisnicandrei committed Jan 16, 2025
1 parent 038e47d commit eb42280
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { of } from 'rxjs';
import { SearchService } from '@search/services/search.service';
import { PublicProfileService } from '@public/services/public-profile/public-profile.service';
import { ArchiveVO, TagVO } from '@models/index';
import { Router } from '@angular/router';
import { ArchiveSearchComponent } from './archive-search.component';

describe('ArchiveSearchComponent', () => {
let component: ArchiveSearchComponent;
let fixture: ComponentFixture<ArchiveSearchComponent>;
let searchService: jasmine.SpyObj<SearchService>;
let publicProfileService: jasmine.SpyObj<PublicProfileService>;
let router: Router;

beforeEach(async () => {
publicProfileService = jasmine.createSpyObj('PublicProfileService', [
Expand All @@ -30,6 +32,10 @@ describe('ArchiveSearchComponent', () => {
FormBuilder,
{ provide: SearchService, useValue: searchService },
{ provide: PublicProfileService, useValue: publicProfileService },
{
provide: Router,
useValue: jasmine.createSpyObj('Router', ['navigate']),
},
],
}).compileComponents();

Expand Down Expand Up @@ -100,7 +106,7 @@ describe('ArchiveSearchComponent', () => {
const mockTag: TagVO = new TagVO({ name: 'Tag1', tagId: 1 });
component.onTagClick([mockTag]);

expect(component.searchForm.value.query).toBe('Tag1');
expect(component.searchForm.value.query).toBe('tag:"Tag1"');
expect(component.tag).toEqual([mockTag]);
});

Expand All @@ -111,4 +117,13 @@ describe('ArchiveSearchComponent', () => {
expect(component.searchResults).toEqual([]);
expect(component.filteredTags).toEqual([]);
});

it('should emit searchByTag event on tagClick', () => {
spyOn(component.searchByTag, 'emit');
component.searchForm.patchValue({ query: 'test query' });

component.onTagClick([new TagVO({ name: 'Tag1', tagId: 1 })]);

expect(component.searchByTag.emit).toHaveBeenCalledWith(1);
});
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/* @format */
import { Component, Output, EventEmitter, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ArchiveVO, TagVO } from '@models/index';
import { ArchiveVO, TagVO, TagVOData } from '@models/index';
import { PublicProfileService } from '@public/services/public-profile/public-profile.service';
import { SearchService } from '@search/services/search.service';
import { catchError, debounceTime, map, of, switchMap, tap } from 'rxjs';
import {
catchError,
debounceTime,
map,
of,
Subscription,
switchMap,
tap,
} from 'rxjs';

@Component({
selector: 'pr-archive-search',
Expand All @@ -13,8 +21,10 @@ import { catchError, debounceTime, map, of, switchMap, tap } from 'rxjs';
})
export class ArchiveSearchComponent implements OnInit {
@Output() search = new EventEmitter<string>();
@Output() searchByTag = new EventEmitter<number>();

private archive: ArchiveVO;
public archive: ArchiveVO;
private valueChangesSubscription: Subscription;

public searchForm: FormGroup;

Expand All @@ -26,7 +36,7 @@ export class ArchiveSearchComponent implements OnInit {
public tags = [];
public filteredTags = [];

public tag: TagVO[] = [];
public tag: TagVOData[] = [];

constructor(
private fb: FormBuilder,
Expand All @@ -53,26 +63,32 @@ export class ArchiveSearchComponent implements OnInit {
}

initFormHandler() {
this.searchForm?.valueChanges
const valueChangesSubscription = this.searchForm?.valueChanges
?.pipe(
debounceTime(100),
map((value) => value.query?.trim() || ''),
tap((term) => {
map((term) => {
return this.searchService.parseSearchTerm(term.query);

Check warning on line 70 in src/app/public/components/archive-search/archive-search.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/public/components/archive-search/archive-search.component.ts#L70

Added line #L70 was not covered by tests
}),
tap(([term, tags]) => {
let value = term ? term : tags[0]?.name;
this.filteredTags = this.tags.filter((tag) =>
tag.name.toLowerCase().includes(term.toLowerCase()),
tag.name.toLowerCase().includes(value?.toLowerCase()),

Check warning on line 75 in src/app/public/components/archive-search/archive-search.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/public/components/archive-search/archive-search.component.ts#L75

Added line #L75 was not covered by tests
);
}),
switchMap((term) => {
if (!term) {
switchMap(([term, tags]) => {
if (!term && !tags.length) {
this.tag = [];
} else {
this.tag = tags;

Check warning on line 82 in src/app/public/components/archive-search/archive-search.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/public/components/archive-search/archive-search.component.ts#L82

Added line #L82 was not covered by tests
}

const archiveId = this.archive?.archiveId;
if (term.length || this.filteredTags.length) {
if (term?.length || this.filteredTags.length) {
this.waiting = true;

return this.searchService
.getResultsInPublicArchive(
term,
term ? term : '',
this.tag.length ? this.tag : [],
archiveId,
3,
Expand All @@ -98,6 +114,7 @@ export class ArchiveSearchComponent implements OnInit {
this.filteredTags = [];
}
});
this.valueChangesSubscription = valueChangesSubscription;
}

public clearForm(): void {
Expand All @@ -109,7 +126,12 @@ export class ArchiveSearchComponent implements OnInit {
}

public onTagClick(tag: TagVO[]): void {
this.searchForm.patchValue({ query: tag[0].name });
this.tag = tag;
this.searchByTag.emit(tag[0].tagId);

this.valueChangesSubscription.unsubscribe();
this.searchForm.patchValue({ query: `tag:"${tag[0].name}"` });

this.initFormHandler();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
<div class="search-box-public-archive">
<pr-archive-search
(search)="onHandleSearch($event)"
(searchByTag)="onTagClick($event)"
></pr-archive-search>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PublicModule } from '@public/public.module';
import { Shallow } from 'shallow-render';
import { of } from 'rxjs';
import { PublicProfileService } from '@public/services/public-profile/public-profile.service';
import { Router } from '@angular/router';
import { PublicArchiveComponent } from './public-archive.component';

const publicProfileServiceMock = {
Expand Down Expand Up @@ -54,4 +55,34 @@ describe('PublicArchiveComponent', () => {
'archive-description-show': true,
});
});

it('should navigate to the correct search URL on handleSearch', async () => {
const { instance, inject } = await shallow.render();
const router = inject(Router);
spyOn(router, 'navigate');

instance.archive = { archiveId: '123' } as any;

instance.onHandleSearch('test-query');

expect(router.navigate).toHaveBeenCalledWith(
['search', '123', 'test-query'],
{ relativeTo: instance.route },
);
});

it('should navigate to the correct search-tag URL on tag click', async () => {
const { instance, inject } = await shallow.render();
const router = inject(Router);
spyOn(router, 'navigate');

instance.archive = { archiveId: '123' } as any;

instance.onTagClick('example-tag');

expect(router.navigate).toHaveBeenCalledWith(
['search-tag', '123', 'example-tag'],
{ relativeTo: instance.route },
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { of, merge, Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { PublicProfileService } from '@public/services/public-profile/public-profile.service';
import { unsubscribeAll } from '@shared/utilities/hasSubscriptions';
import { SearchService } from '@search/services/search.service';
import { RouteData } from '@root/app/app.routes';

@Component({
Expand Down Expand Up @@ -51,9 +50,8 @@ export class PublicArchiveComponent implements OnInit, OnDestroy {
subscriptions: Subscription[] = [];
constructor(
private router: Router,
private route: ActivatedRoute,
public route: ActivatedRoute,
private publicProfile: PublicProfileService,
private searchService: SearchService,
) {}

ngOnInit(): void {
Expand Down Expand Up @@ -123,4 +121,17 @@ export class PublicArchiveComponent implements OnInit, OnDestroy {
toggleProfileInformation(): void {
this.showProfileInformation = !this.showProfileInformation;
}

public onTagClick(tagName: string): void {
try {
this.router.navigate(
['search-tag', this.archive.archiveId, `${tagName}`],
{
relativeTo: this.route,
},
);
} catch (err) {
console.error(err);

Check warning on line 134 in src/app/public/components/public-archive/public-archive.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/public/components/public-archive/public-archive.component.ts#L134

Added line #L134 was not covered by tests
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/* @format */
import { ActivatedRoute, Router } from '@angular/router';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { Subscription } from 'rxjs';
import { FolderVO, RecordVO } from '@models/index';
import { FolderVO, RecordVO, TagVO } from '@models/index';
import { SearchService } from '../../../search/services/search.service';

@Component({
Expand All @@ -15,6 +14,7 @@ export class PublicSearchResultsComponent implements OnInit, OnDestroy {
public searchResults = [];
public waiting = false;
public query = '';
public tags = [];

public archivePath = ['..', '..', '..'];

Expand All @@ -25,17 +25,18 @@ export class PublicSearchResultsComponent implements OnInit, OnDestroy {
private router: Router,
private route: ActivatedRoute,
private searchService: SearchService,
private location: Location,
) {}

ngOnInit(): void {
//get the query param from the route
if (this.route.params) {
this.paramsSubscription = this.route.params.subscribe((params) => {
this.archivePath = ['/p/archive', params.publicArchiveNbr];
this.query = params.query;

this.query = params.query ? params.query : '';
this.tags = params.tagId ? [new TagVO({ tagId: params.tagId })] : [];

this.searchSubscription = this.searchService
.getResultsInPublicArchive(params.query, [], params.archiveId)
.getResultsInPublicArchive(this.query, this.tags, params.archiveId)
.subscribe((response) => {
if (response) {
this.searchResults = response.ChildItemVOs;
Expand Down
4 changes: 4 additions & 0 deletions src/app/public/public.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export const routes: RoutesWithData = [
path: 'search/:archiveId/:query',
component: PublicSearchResultsComponent,
},
{
path: 'search-tag/:archiveId/:tagId',
component: PublicSearchResultsComponent,
},
{
path: 'profile',
component: PublicProfileComponent,
Expand Down
Loading

0 comments on commit eb42280

Please sign in to comment.