Newer
Older

Eduard Frankford
committed
import { HttpResponse } from '@angular/common/http';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { Router } from '@angular/router';
import { faFolder } from '@fortawesome/free-solid-svg-icons';
import { ReviewManagementService } from 'app/admin/review-management/review-management.service';
import { ApplicationInfoService } from 'app/core/application/applicationInfo.service';
import { Account } from 'app/core/auth/account.model';
import { AccountService } from 'app/core/auth/account.service';
import { AlertService } from 'app/core/util/alert.service';

Eduard Frankford
committed
import { LikesService } from 'app/entities/likes/likes.service';
import { ExerciseService } from 'app/exercise/service/exercise.service';

Eduard Frankford
committed
import { SearchService } from 'app/search/service/search-service';

Eduard Frankford
committed
import { ShoppingBasketInfo, ShoppingBasketRedirectInfoDTO } from 'app/shared/model/basket/shopping-basket-info.model';
import { Person } from 'app/shared/model/person.model';
import { ExtendedSearchResultDTO, PluginActionInfo, SearchResultDTO } from 'app/shared/model/search/search-result-dto.model';

Eduard Frankford
committed
import { PluginService } from 'app/shared/service/plugin-service';
import { WatchlistManager } from 'app/shared/watchlist/watchlist-manager';

Eduard Frankford
committed
import { Subscription } from 'rxjs';
selector: 'jhi-exercise-modal-details',
templateUrl: './exercise-details-modal.component.html',
export class ExerciseDetailsModalComponent {
@Output() exerciseChangedEvent = new EventEmitter<SearchResultDTO>();
@Input() get referencedExercise(): SearchResultDTO | undefined {
return this.exercise;
}
set referencedExercise(exercise: SearchResultDTO | undefined) {
this.exercise = exercise as ExtendedSearchResultDTO;
}
exercise: ExtendedSearchResultDTO | undefined;
constructor(private watchlistManager: WatchlistManager) {}
handleExerciseChangedEvent(exercise: SearchResultDTO): void {
@Component({
selector: 'jhi-exercise-nonmodal-details',
templateUrl: './exercise-details-nonmodal.component.html',
})
export class ExerciseDetailsNonModalComponent {
@Input() exercise: ExtendedSearchResultDTO | undefined;
@Component({
selector: 'jhi-exercise-header',
templateUrl: './exerciseComponents/exercise-header.component.html',
styleUrls: ['./exerciseComponents/exercise-header.component.scss'],
})
export class ExerciseHeaderComponent {
@Input() exercise: ExtendedSearchResultDTO | undefined;
/**
* correct missing image urls
*/
correctImageURL(event: Event): void {
const srcElement = event.srcElement as HTMLImageElement;
if (srcElement) {
srcElement.src = '/content/images/Logo_codeAbility_4c_300dpi_RGB3.gif';
}
}
}
@Component({
selector: 'jhi-exercise-body',
templateUrl: './exerciseComponents/exercise-body.component.html',
styleUrls: ['./exerciseComponents/exercise-body.component.scss'],
})
export class ExerciseBodyComponent implements OnInit, OnDestroy {
@Output() exerciseChangedEvent = new EventEmitter<SearchResultDTO>();
exercise: ExtendedSearchResultDTO | undefined;
markDownExercise: SearchResultDTO | undefined;
account: Account | null = null;
authSubscription?: Subscription;
hasLiked: boolean | null = null;
likeSubscription?: Subscription;
authenticated = false;
@Input() get referencedExercise(): SearchResultDTO | undefined {
return this.exercise;
}
set referencedExercise(exercise: SearchResultDTO | undefined) {
this.gitlabIsAccessible = false;
this.exercise = exercise as ExtendedSearchResultDTO;
if (exercise) {
this.updateGitIsAccessibleForUser();
}
}
oerLink?: string;
oerExerciseMatch = /([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$/;
private reviewManagementService: ReviewManagementService,
private accountService: AccountService,
protected pluginService: PluginService,
private searchService: SearchService,
private likesService: LikesService,
private jhiAlertService: AlertService,
private watchlistManager: WatchlistManager,
private exerciseService: ExerciseService,
private applicationInfoService: ApplicationInfoService,
private router: Router
) {}
toggleWithChildren() {
this.downloadWithChildren = !this.downloadWithChildren;
}
selectREADME(): void {
this.markDownExercise = this.exercise;
}
hasChildren(): boolean {
return (
this.exercise !== undefined &&
this.exercise !== null &&
this.exercise.file !== undefined &&
this.exercise.file !== null &&
this.exercise.file.children !== undefined &&
this.exercise.file.children !== null &&
this.exercise.file.children.length > 0
updateGitIsAccessibleForUser(): void {
const projectIsPrivate: boolean = this.exercise?.project.visibilty == 'private';
const exceptIsEmpty: boolean =
!this.exercise?.metadata.publicVisibility?.except || this.exercise?.metadata.publicVisibility?.except.length == 0;
if (!projectIsPrivate && exceptIsEmpty) {
this.gitlabIsAccessible = true;
return;
}
if (!this.isAuthenticated()) {
this.gitlabIsAccessible = false;
return;
}
this.exerciseService
.hasUserAccessToGitlabRepo(this.exercise!.exerciseId)
.subscribe((accessible: boolean) => (this.gitlabIsAccessible = accessible));
}
public startAction(action: PluginActionInfo, exercise: SearchResultDTO): void {
const basketInfo: ShoppingBasketInfo = {
plugin: action.plugin,
action: action.action,
this.pluginService.getRedirectLink(basketInfo).subscribe({
next: (redirectInfo: ShoppingBasketRedirectInfoDTO) => {
window.open(redirectInfo.redirectURL, action.action);
},
error: () => alert('Search failed'),
});
this.exportProject(this.exercise!.exerciseId);
}
exportProject(exerciseId: string) {
const recursion = this.downloadWithChildren ? 'WITH_DESCENDANTS' : 'JUST_PROJECT';
return this.searchService.exportProject(exerciseId, recursion).subscribe({
next: (response: HttpResponse<Blob>) => {
this.jhiAlertService.addAlert({
type: 'success',
translationKey: 'artemisApp.programmingExercise.export.successMessage',
});
if (response.body) {
const zipFile = new Blob([response.body], { type: 'application/zip' });
const url = window.URL.createObjectURL(zipFile);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', response.headers.get('filename')!);
document.body.appendChild(link); // Required for FF
link.click();
window.URL.revokeObjectURL(url);
}
},
error: () => alert('Unable to export exercise. Please log in to export, or check your git lab permissions.'),
});

Michael Breu
committed
getGitLabUrl(): string {
return this.reviewManagementService.getGitLabUrl(this.exercise!);

Michael Breu
committed
}
openLink(link: string): void {
window.open(link);
}
searchChildren(parentId: string): void {
this.router.navigate(['/search'], { queryParams: { p: parentId } });
}
toParent(parentId: string): void {
this.exerciseService.loadExercise(parentId).subscribe({
next: searchResult => {
this.exercise = this.exerciseService.populateExerciseWithData(searchResult);
this.exerciseChangedEvent.emit(this.exercise);
},
error: () => {
isLoggedIn(): boolean {
return this.accountService.isAuthenticated();
}
public isEditable(): boolean {
if (!this.exercise) return false;
if (!this.exercise.project.url) return false;
const matchGroups = this.exercise.project.url.match(this.oerExerciseMatch);
if (!matchGroups) return false;
// Just for Testing: allow every edit
if (this.oerLink) return true;
const email = this.accountService.getUserEMail();
if (!email || email == '') return false;
// test all: creator, publisher
let potentialEditors: Person[] = [];
potentialEditors = potentialEditors.concat(this.exercise.metadata.creator);
potentialEditors = potentialEditors.concat(this.exercise.metadata.publisher);
for (const pE of potentialEditors) {
if (pE.email.localeCompare(email, undefined, { sensitivity: 'base' }) === 0) return true;
}
return false;
}
public getOEResourceLink(): string {
if (this.oerLink) {
const matchGroups = this.exercise!.project.url.match(this.oerExerciseMatch);
if (!matchGroups) return '';
const guid = matchGroups[1];
return this.oerLink.toString() + '/en/update/1/' + guid;
}
return '';
}
likeAction(): void {
// to do call like service
this.likesService.likeExercise(this.exercise!.exerciseId).subscribe(() =>
console.log('Liked post' + this.exercise!.exerciseId)
);
this.exercise!.numberOfLikes = this.exercise!.numberOfLikes + 1;
this.exercise!.userHasLiked = true;
}
unlikeAction(): void {
// to do call like service
this.likesService.unlikeExercise(this.exercise!.exerciseId);
this.exercise!.numberOfLikes = this.exercise!.numberOfLikes - 1;
this.exercise!.userHasLiked = false;
}
public isAuthenticated(): boolean {
return this.accountService.isAuthenticated();
}
ngOnInit(): void {
this.bookmarked = this.watchlistManager.isExerciseOnCurrentWatchlist(this.exercise!);
this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account));
this.applicationInfoService.loadOerLink().subscribe({
next: (res: string) => {
console.error(error),
});
}
ngOnDestroy(): void {
if (this.authSubscription) {
this.authSubscription.unsubscribe();
}
}