import { Component, OnInit, OnDestroy } from '@angular/core'; import { HttpHeaders, HttpResponse } from '@angular/common/http'; import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs'; import { JhiEventManager, JhiParseLinks } from 'ng-jhipster'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { IUserWatchList } from 'app/shared/model/user-watch-list.model'; import { Exercise } from 'app/shared/model/exercise.model'; import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants'; import { UserWatchListService } from 'app/entities/user-watch-list/user-watch-list.service'; import { UserWatchListDeleteDialogComponent } from './user-watch-list-delete-dialog.component'; import { SearchResultsDTO } from 'app/shared/model/search/search-results-dto.model'; import { SearchResultDTO, PluginActionInfo, equalPluginActionInfo } from 'app/shared/model/search/search-result-dto.model'; import { WatchlistManager } from 'app/shared/watchlist/watchlist-manager'; import { ShoppingBasketInfo, ShoppingBasketRedirectInfoDTO } from 'app/shared/model/basket/shopping-basket-info.model'; import { PluginService } from 'app/shared/service/plugin-service'; import * as lodash from "lodash"; @Component({ selector: 'jhi-bookmarks', styleUrls: ['./bookmarks.component.scss'], templateUrl: './bookmarks.component.html', }) export class BookmarkComponent implements OnInit, OnDestroy { userWatchLists: IUserWatchList[]; selectedWatchList?: IUserWatchList; eventSubscriber?: Subscription; itemsPerPage: number; links: any; page: number; predicate: string; ascending: boolean; currentSearch: string; results: Exercise[] = []; selectedResult?: Exercise; hitCount = 0; constructor( protected userWatchListService: UserWatchListService, protected eventManager: JhiEventManager, protected modalService: NgbModal, protected parseLinks: JhiParseLinks, protected activatedRoute: ActivatedRoute, protected watchlistManager: WatchlistManager, protected pluginService: PluginService, ) { this.userWatchLists = []; this.itemsPerPage = ITEMS_PER_PAGE; this.page = 0; this.links = { last: 0, }; this.predicate = 'id'; this.ascending = true; this.currentSearch = this.activatedRoute.snapshot && this.activatedRoute.snapshot.queryParams['search'] ? this.activatedRoute.snapshot.queryParams['search'] : ''; } loadAll(): void { if (this.currentSearch) { this.userWatchListService .searchForCurrentUser({ query: this.currentSearch, page: this.page, size: this.itemsPerPage, sort: this.sort(), }) .subscribe((res: HttpResponse<IUserWatchList[]>) => {this.paginateUserWatchLists(res.body, res.headers); }); return; } this.userWatchListService .findMyWatchlists({ page: this.page, size: this.itemsPerPage, sort: this.sort(), }) .subscribe((res: HttpResponse<IUserWatchList[]>) => { this.paginateUserWatchLists(res.body, res.headers); this.loadCurrent(); }); } private loadCurrent(): void { this.userWatchLists.every( (uwl) => { if(this.isSelected(uwl)) { this.view(uwl); return false; } return true;}) } reset(): void { this.page = 0; this.userWatchLists = []; this.loadAll(); } loadPage(page: number): void { this.page = page; this.loadAll(); } selectExercise(exercise: Exercise): void { this.selectedResult = exercise; } search(query: string): void { this.userWatchLists = []; this.links = { last: 0, }; this.page = 0; if (query) { this.predicate = '_score'; this.ascending = false; } else { this.predicate = 'id'; this.ascending = true; } this.currentSearch = query; this.loadAll(); } ngOnInit(): void { this.loadAll(); this.registerChangeInUserWatchLists(); } ngOnDestroy(): void { if (this.eventSubscriber) { this.eventManager.destroy(this.eventSubscriber); } } trackId(index: number, item: IUserWatchList): number { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion return item.id!; } registerChangeInUserWatchLists(): void { this.eventSubscriber = this.eventManager.subscribe('userWatchListListModification', () => this.reset()); } private parseSearchResultsDTO(searchResultsDTO: SearchResultsDTO): Exercise[] { this.hitCount = searchResultsDTO.hitCount; // fix string to date conversion: unfortunatelly dates are not converted correctly :-() searchResultsDTO.searchResult.forEach(hit => { // eslint-disable-next-line @typescript-eslint/camelcase hit.project.last_activity_at = new Date(hit.project.last_activity_at); // eslint-disable-next-line @typescript-eslint/camelcase hit.file.indexing_date = new Date(hit.file.indexing_date); }); return searchResultsDTO.searchResult.map(this.searchResultToExercise); } private searchResultToExercise(searchResult: SearchResultDTO): Exercise { return { title: searchResult.metadata.title, license: searchResult.metadata.license, description: searchResult.metadata.description, programmingLanguages: searchResult.metadata.programmingLanguage, languages: searchResult.metadata.language, creators: searchResult.metadata.creator, contributor: searchResult.metadata.contributor, publisher: searchResult.metadata.publisher, imageURL: searchResult.metadata.image, rating: searchResult.ranking5, lastUpdate: searchResult.project.last_activity_at, timeRequired: searchResult.metadata.timeRequired, requires: searchResult.metadata.requires, deprecated: searchResult.metadata.deprecated, difficulty: searchResult.metadata.difficulty, educationLevel: searchResult.metadata.educationLevel, format: searchResult.metadata.format, keyword: searchResult.metadata.keyword, status: searchResult.metadata.status, type: searchResult.metadata.type, structure: searchResult.metadata.structure, version: searchResult.metadata.version, metadataVersion: searchResult.metadata.metadataVersion, gitlabURL: searchResult.project.url, originalResult: searchResult, views: searchResult.views, downloads: searchResult.downloads, }; } delete(userWatchList: IUserWatchList): void { const modalRef = this.modalService.open(UserWatchListDeleteDialogComponent, { size: 'lg', backdrop: 'static' }); modalRef.componentInstance.userWatchList = userWatchList; } sort(): string[] { const result = [this.predicate + ',' + (this.ascending ? 'asc' : 'desc')]; if (this.predicate !== 'id') { result.push('id'); } return result; } view(userWatchList: IUserWatchList): void { this.hitCount = 0; this.page = 0; this.results = []; this.selectedWatchList = userWatchList; this.watchlistManager.setCurrentWatchList(userWatchList.name!); this.onScroll(); } onScroll(): void { if (this.selectedWatchList) { this.userWatchListService.findExercises(this.selectedWatchList, this.page).subscribe( (data: SearchResultsDTO) => { const searchResults = this.parseSearchResultsDTO(data); this.results = this.results.concat(searchResults); ++this.page; }, () => alert('Search failed') ) } } isSelected(userWatchList: IUserWatchList) { return this.watchlistManager.getCurrentWatchList() && (userWatchList.id === this.watchlistManager.getCurrentWatchList()!.userWatchList.id); } protected paginateUserWatchLists(data: IUserWatchList[] | null, headers: HttpHeaders): void { const headersLink = headers.get('link'); this.links = this.parseLinks.parse(headersLink ? headersLink : ''); if (data) { for (let i = 0; i < data.length; i++) { this.userWatchLists.push(data[i]); } } } getCommonActions(): PluginActionInfo[] { const result = lodash.chain(this.results) .map(function(ex: Exercise) { return ex.originalResult.supportedActions }) .flatten() .uniqWith(equalPluginActionInfo); return result.value(); } startAction(action: PluginActionInfo): void { const selectedExercises = lodash.chain(this.results) .map(function(ex: Exercise) { return ex.originalResult }) .filter(function(sr: SearchResultDTO) { return sr.supportedActions.some(function(a: PluginActionInfo) {return equalPluginActionInfo(a, action)}) }) const basketInfo: ShoppingBasketInfo = { plugin: action.plugin, action: action.action, itemInfos: selectedExercises.value(), }; this.pluginService.getRedirectLink(basketInfo).subscribe( (redirectInfo: ShoppingBasketRedirectInfoDTO) => { // alert('redirecting to ' + redirectInfo.redirectURL); // location.href = redirectInfo.redirectURL; window.open(redirectInfo.redirectURL, action.action); }, () => alert('Search failed') ); } }