This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Skip to content
Snippets Groups Projects
Commit d145dd93 authored by Michael Breu's avatar Michael Breu
Browse files

some minor fixes

parent e02d8d29
Branches
3 merge requests!132Bringing July Release to production,!128Fixing #315 and #319,!127Draft: Resolve "Exercises in der Sharing Plattform sollten direkt per URL adressiert werden können."
Showing
with 483 additions and 486 deletions
File added
......@@ -4,13 +4,13 @@
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<jhi-exercise-header [exercise]="exercise" style="display:flex;"></jhi-exercise-header>
<jhi-exercise-header [exercise]="exercise" style="display: flex"></jhi-exercise-header>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<jhi-exercise-body [exercise]="exercise"></jhi-exercise-body>
<jhi-exercise-body [exercise]="exercise" (exerciseChangedEvent)="handleExerciseChangedEvent($event)"></jhi-exercise-body>
</div>
<!-- Modal footer -->
......
<div *ngIf="exercise">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<jhi-exercise-header [exercise]="exercise" style="display:flex;"></jhi-exercise-header>
</div>
<!-- Modal body -->
<div class="modal-body">
<jhi-exercise-body [exercise]="exercise"></jhi-exercise-body>
</div>
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<jhi-exercise-header [exercise]="exercise" style="display: flex"></jhi-exercise-header>
</div>
<!-- Modal body -->
<div class="modal-body">
<jhi-exercise-body [exercise]="exercise"></jhi-exercise-body>
</div>
</div>
</div>
<jhi-markdown-viewer [exercise]="exercise"></jhi-markdown-viewer>
</div>
......@@ -26,256 +26,254 @@ export class ExerciseDetailsModalComponent {
@Input() exercise: Exercise | undefined;
@Output() exerciseChangedEvent = new EventEmitter<Exercise>();
handleExerciseChangedEvent(exercise: Exercise): void {
this.exerciseChangedEvent.emit(exercise);
}
}
@Component({
selector: 'jhi-exercise-nonmodal-details',
templateUrl: './exercise-details-nonmodal.component.html',
styleUrls: ['./exercise-details.component.scss'],
})
export class ExerciseDetailsNonModalComponent {
@Input() exercise: Exercise | undefined;
}
selector: 'jhi-exercise-nonmodal-details',
templateUrl: './exercise-details-nonmodal.component.html',
styleUrls: ['./exercise-details.component.scss'],
})
export class ExerciseDetailsNonModalComponent {
@Input() exercise: Exercise | undefined;
}
@Component({
selector: 'jhi-exercise-header',
templateUrl: './exerciseComponents/exercise-header.component.html',
styleUrls: ['./exerciseComponents/exercise-header.component.scss'],
})
export class ExerciseHeaderComponent {
@Input() exercise: Exercise | 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';
}
}
selector: 'jhi-exercise-header',
templateUrl: './exerciseComponents/exercise-header.component.html',
styleUrls: ['./exerciseComponents/exercise-header.component.scss'],
})
export class ExerciseHeaderComponent {
@Input() exercise: Exercise | 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 {
@Input() exercise: Exercise | undefined;
@Output() exerciseChangedEvent = new EventEmitter<Exercise>();
downloadWithChildren = false;
markDownExercise: Exercise | undefined;
account: Account | null = null;
authSubscription?: Subscription;
hasLiked: Boolean | null = null;
likeSubscription?: Subscription;
authenticated = false;
treeIcon = faFolder;
oerLink?: String;
oerExerciseMatch = new RegExp('/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$');
constructor(
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.originalResult !== undefined &&
this.exercise.originalResult !== null &&
this.exercise.originalResult.file !== undefined &&
this.exercise.originalResult.file !== null &&
this.exercise.originalResult.file.children !== undefined &&
this.exercise.originalResult.file.children !== null &&
this.exercise.originalResult.file.children.length > 0
);
}
public startAction(action: PluginActionInfo, exercise: Exercise): void {
const basketInfo: ShoppingBasketInfo = {
plugin: action.plugin,
action: action.action,
itemInfos: [exercise.originalResult],
};
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')
);
}
public download(): void {
this.exportProject(this.exercise!.originalResult.exerciseId);
}
exportProject(exerciseId: string) {
const recursion = this.downloadWithChildren ? 'WITH_DESCENDANTS' : 'JUST_PROJECT';
return this.searchService.exportProject(exerciseId, recursion).subscribe(
(response: HttpResponse<Blob>) => {
this.jhiAlertService.addAlert({
type: 'success',
translationKey: 'artemisApp.programmingExercise.export.successMessage',
});
// success('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);
}
},
() => alert('Unable to export exercise. Please log in to export, or check your git lab permissions.')
);
}
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(searchResult => {
this.exercise = searchResultToExercise(searchResult);
this.exercise = this.exerciseService.populateExerciseWithData(this.exercise);
this.exerciseChangedEvent.emit(this.exercise);
}),
() => {
alert('parent cannot be loaded');
};
}
handleForCurrentWatchlist(e: Exercise): void {
if (this.watchlistManager.isExerciseOnCurrentWatchlist(e)) {
e.numberOfWatchlistEntries = e.numberOfWatchlistEntries - 1;
} else {
e.numberOfWatchlistEntries = e.numberOfWatchlistEntries + 1;
}
this.watchlistManager.handleCheckForCurrentWatchlist(e);
}
public isEditable(): boolean {
if (!this.exercise) return false;
if (!this.exercise.gitlabURL) return false;
const matchGroups = this.exercise.gitlabURL.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.concat(this.exercise.contributor);
potentialEditors = potentialEditors.concat(this.exercise.creator);
potentialEditors = potentialEditors.concat(this.exercise.publisher);
for (let i = 0; i < potentialEditors.length; i++) {
if (potentialEditors[i].email.localeCompare(email, undefined, { sensitivity: 'base' }) === 0) return true;
}
return false;
}
public getOEResourceLink(): string {
if (this.oerLink) {
const matchGroups = this.exercise!.gitlabURL.match(this.oerExerciseMatch);
if (!matchGroups) return '';
const guid = matchGroups[1];
return this.oerLink.toString() + '/en/update/1/' + guid;
}
return '';
}
isOnCurrentWatchlist(e: Exercise): boolean {
return this.watchlistManager.isExerciseOnCurrentWatchlist(e);
}
likeAction(): void {
// to do call like service
this.likesService.likeExercise(this.exercise!.originalResult.exerciseId).subscribe(() =>
// eslint-disable-next-line no-console
console.log('Liked post' + this.exercise!.originalResult.exerciseId)
);
this.exercise!.numberOfLikes = this.exercise!.numberOfLikes + 1;
this.exercise!.userHasLiked = true;
// eslint-disable-next-line no-console
console.log(`Reloaded number of likes is ${this.exercise!.numberOfLikes}`);
}
unlikeAction(): void {
// to do call like service
this.likesService.unlikeExercise(this.exercise!.originalResult.exerciseId).subscribe(() =>
// eslint-disable-next-line no-console
console.log('Unliked post ' + this.exercise!.originalResult.exerciseId)
);
this.exercise!.numberOfLikes = this.exercise!.numberOfLikes - 1;
this.exercise!.userHasLiked = false;
// eslint-disable-next-line no-console
console.log(`Reloaded number of likes is ${this.exercise!.numberOfLikes}`);
}
public isAuthenticated(): boolean {
return this.accountService.isAuthenticated();
}
ngOnInit(): void {
this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account));
this.applicationInfoService.loadOerLink().subscribe(
(res: string) => {
this.oerLink = res;
},
error =>
// eslint-disable-next-line no-console
console.error(error)
);
}
ngOnDestroy(): void {
if (this.authSubscription) {
this.authSubscription.unsubscribe();
}
}
selector: 'jhi-exercise-body',
templateUrl: './exerciseComponents/exercise-body.component.html',
styleUrls: ['./exerciseComponents/exercise-body.component.scss'],
})
export class ExerciseBodyComponent implements OnInit, OnDestroy {
@Input() exercise: Exercise | undefined;
@Output() exerciseChangedEvent = new EventEmitter<Exercise>();
downloadWithChildren = false;
markDownExercise: Exercise | undefined;
account: Account | null = null;
authSubscription?: Subscription;
hasLiked: Boolean | null = null;
likeSubscription?: Subscription;
authenticated = false;
treeIcon = faFolder;
oerLink?: String;
oerExerciseMatch = new RegExp('/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$');
constructor(
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.originalResult !== undefined &&
this.exercise.originalResult !== null &&
this.exercise.originalResult.file !== undefined &&
this.exercise.originalResult.file !== null &&
this.exercise.originalResult.file.children !== undefined &&
this.exercise.originalResult.file.children !== null &&
this.exercise.originalResult.file.children.length > 0
);
}
public startAction(action: PluginActionInfo, exercise: Exercise): void {
const basketInfo: ShoppingBasketInfo = {
plugin: action.plugin,
action: action.action,
itemInfos: [exercise.originalResult],
};
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')
);
}
public download(): void {
this.exportProject(this.exercise!.originalResult.exerciseId);
}
exportProject(exerciseId: string) {
const recursion = this.downloadWithChildren ? 'WITH_DESCENDANTS' : 'JUST_PROJECT';
return this.searchService.exportProject(exerciseId, recursion).subscribe(
(response: HttpResponse<Blob>) => {
this.jhiAlertService.addAlert({
type: 'success',
translationKey: 'artemisApp.programmingExercise.export.successMessage',
});
// success('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);
}
},
() => alert('Unable to export exercise. Please log in to export, or check your git lab permissions.')
);
}
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(searchResult => {
this.exercise = searchResultToExercise(searchResult);
this.exercise = this.exerciseService.populateExerciseWithData(this.exercise);
this.exerciseChangedEvent.emit(this.exercise);
}),
() => {
alert('parent cannot be loaded');
};
}
handleForCurrentWatchlist(e: Exercise): void {
if (this.watchlistManager.isExerciseOnCurrentWatchlist(e)) {
e.numberOfWatchlistEntries = e.numberOfWatchlistEntries - 1;
} else {
e.numberOfWatchlistEntries = e.numberOfWatchlistEntries + 1;
}
this.watchlistManager.handleCheckForCurrentWatchlist(e);
}
public isEditable(): boolean {
if (!this.exercise) return false;
if (!this.exercise.gitlabURL) return false;
const matchGroups = this.exercise.gitlabURL.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.concat(this.exercise.contributor);
potentialEditors = potentialEditors.concat(this.exercise.creator);
potentialEditors = potentialEditors.concat(this.exercise.publisher);
for (let i = 0; i < potentialEditors.length; i++) {
if (potentialEditors[i].email.localeCompare(email, undefined, { sensitivity: 'base' }) === 0) return true;
}
return false;
}
public getOEResourceLink(): string {
if (this.oerLink) {
const matchGroups = this.exercise!.gitlabURL.match(this.oerExerciseMatch);
if (!matchGroups) return '';
const guid = matchGroups[1];
return this.oerLink.toString() + '/en/update/1/' + guid;
}
return '';
}
isOnCurrentWatchlist(e: Exercise): boolean {
return this.watchlistManager.isExerciseOnCurrentWatchlist(e);
}
likeAction(): void {
// to do call like service
this.likesService.likeExercise(this.exercise!.originalResult.exerciseId).subscribe(() =>
// eslint-disable-next-line no-console
console.log('Liked post' + this.exercise!.originalResult.exerciseId)
);
this.exercise!.numberOfLikes = this.exercise!.numberOfLikes + 1;
this.exercise!.userHasLiked = true;
// eslint-disable-next-line no-console
console.log(`Reloaded number of likes is ${this.exercise!.numberOfLikes}`);
}
unlikeAction(): void {
// to do call like service
this.likesService.unlikeExercise(this.exercise!.originalResult.exerciseId).subscribe(() =>
// eslint-disable-next-line no-console
console.log('Unliked post ' + this.exercise!.originalResult.exerciseId)
);
this.exercise!.numberOfLikes = this.exercise!.numberOfLikes - 1;
this.exercise!.userHasLiked = false;
// eslint-disable-next-line no-console
console.log(`Reloaded number of likes is ${this.exercise!.numberOfLikes}`);
}
public isAuthenticated(): boolean {
return this.accountService.isAuthenticated();
}
ngOnInit(): void {
this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account));
this.applicationInfoService.loadOerLink().subscribe(
(res: string) => {
this.oerLink = res;
},
error =>
// eslint-disable-next-line no-console
console.error(error)
);
}
ngOnDestroy(): void {
if (this.authSubscription) {
this.authSubscription.unsubscribe();
}
}
}
<div class="container-fluid" *ngIf="exercise">
<ng-template #helpComingSoon> {{ 'exercise.comingSoon' | translate }}</ng-template>
<div class="container-fluid" *ngIf="exercise">
<ng-template #helpComingSoon> {{ 'exercise.comingSoon' | translate }}</ng-template>
<div *ngIf="exercise.description" class="row">
<p style="padding-bottom: 15px; text-align: justify">{{ exercise.description }}</p>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6" style="margin-bottom: 15px">
<p style="text-align: left"><strong jhiTranslate="exercise.details.details"></strong></p>
<hr />
<div *ngIf="exercise.description" class="row">
<p style="padding-bottom: 15px; text-align: justify">{{ exercise.description }}</p>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6" style="margin-bottom: 15px">
<p style="text-align: left"><strong jhiTranslate="exercise.details.details"></strong></p>
<hr />
<!-- modal rating-->
<div *ngIf="exercise.rating" class="positionRating">
<div [ngbTooltip]="helpForRating" style="float: left">
<p class="card-text" jhiTranslate="exercise.details.accuracy"></p>
</div>
<div class="star-container">
<span
class="star"
*ngFor="let starNumber of [1, 2, 3, 4, 5]"
[ngClass]="{ 'star-marked': exercise.rating >= starNumber, 'star-unmarked': exercise.rating < starNumber }"
>
</span>
</div>
<ng-template #helpForRating> {{ 'exercise.details.rating' | translate }} </ng-template>
</div>
<!-- modal rating end-->
<!-- modal rating-->
<div *ngIf="exercise.rating" class="positionRating">
<div [ngbTooltip]="helpForRating" style="float: left">
<p class="card-text" jhiTranslate="exercise.details.accuracy"></p>
</div>
<div class="star-container">
<span
class="star"
*ngFor="let starNumber of [1, 2, 3, 4, 5]"
[ngClass]="{ 'star-marked': exercise.rating >= starNumber, 'star-unmarked': exercise.rating < starNumber }"
>
</span>
</div>
<ng-template #helpForRating> {{ 'exercise.details.rating' | translate }} </ng-template>
</div>
<!-- modal rating end-->
<div *ngIf="!exercise.userHasLiked" class="positionRating">
<div style="float: left">
<div>
<button
[ngbTooltip]="helpForLike"
*ngIf="isAuthenticated()"
type="button"
class="btn positionLike"
(click)="likeAction()"
[disabled]="!isAuthenticated()"
>
<fa-icon [icon]="['far', 'heart']"></fa-icon>
</button>
<span [ngbTooltip]="helpForLikeNotLoggedIn">
<button *ngIf="!isAuthenticated()" type="button" class="btn positionLike" (click)="likeAction()" [disabled]="true">
<fa-icon [icon]="['far', 'heart']"></fa-icon>
</button>
</span>
</div>
</div>
<div class="star-container">
<span>
{{ exercise.numberOfLikes }}
</span>
</div>
<div *ngIf="!exercise.userHasLiked" class="positionRating">
<div style="float: left">
<div>
<button
[ngbTooltip]="helpForLike"
*ngIf="isAuthenticated()"
type="button"
class="btn positionLike"
(click)="likeAction()"
[disabled]="!isAuthenticated()"
>
<fa-icon [icon]="['far', 'heart']"></fa-icon>
</button>
<span [ngbTooltip]="helpForLikeNotLoggedIn">
<button *ngIf="!isAuthenticated()" type="button" class="btn positionLike" (click)="likeAction()" [disabled]="true">
<fa-icon [icon]="['far', 'heart']"></fa-icon>
</button>
</span>
</div>
</div>
<div class="star-container">
<span>
{{ exercise.numberOfLikes }}
</span>
</div>
<ng-template #helpForLike> {{ 'exercise.details.like' | translate }}</ng-template>
<ng-template #helpForLikeNotLoggedIn> {{ 'exercise.details.likeLogin' | translate }} </ng-template>
</div>
<!-- modal views end-->
<ng-template #helpForLike> {{ 'exercise.details.like' | translate }}</ng-template>
<ng-template #helpForLikeNotLoggedIn> {{ 'exercise.details.likeLogin' | translate }} </ng-template>
</div>
<!-- modal views end-->
<div *ngIf="exercise.userHasLiked" class="positionRating">
<div style="float: left">
<div>
<button
[ngbTooltip]="helpForUnLike"
*ngIf="exercise.userHasLiked"
type="button"
class="btn positionLike"
(click)="unlikeAction()"
[disabled]="!isAuthenticated()"
>
<fa-icon class="rediconcolor" icon="heart"></fa-icon>
</button>
</div>
</div>
<div class="star-container">
<span>
{{ exercise.numberOfLikes }}
</span>
</div>
<ng-template #helpForUnLike> {{ 'exercise.details.unlike' | translate }} </ng-template>
</div>
<div *ngIf="exercise.userHasLiked" class="positionRating">
<div style="float: left">
<div>
<button
[ngbTooltip]="helpForUnLike"
*ngIf="exercise.userHasLiked"
type="button"
class="btn positionLike"
(click)="unlikeAction()"
[disabled]="!isAuthenticated()"
>
<fa-icon class="rediconcolor" icon="heart"></fa-icon>
</button>
</div>
</div>
<div class="star-container">
<span>
{{ exercise.numberOfLikes }}
</span>
</div>
<ng-template #helpForUnLike> {{ 'exercise.details.unlike' | translate }} </ng-template>
</div>
<div *ngIf="exercise.views" class="positionRating">
<div style="float: left">
<div [ngbTooltip]="helpForViews">
<fa-icon icon="eye"></fa-icon>
</div>
</div>
<div class="star-container">
<span>
{{ exercise.views }}
</span>
</div>
<ng-template #helpForViews> {{ 'exercise.details.views' | translate }}</ng-template>
</div>
<!-- modal views end-->
<div *ngIf="exercise.views" class="positionRating">
<div style="float: left">
<div [ngbTooltip]="helpForViews">
<fa-icon icon="eye"></fa-icon>
</div>
</div>
<div class="star-container">
<span>
{{ exercise.views }}
</span>
</div>
<ng-template #helpForViews> {{ 'exercise.details.views' | translate }}</ng-template>
</div>
<!-- modal views end-->
<div *ngIf="exercise.downloads >= 0" class="positionRating">
<div [ngbTooltip]="helpForDownloads" style="float: left">
<fa-icon icon="download"></fa-icon>
</div>
<div class="star-container">
<span>
{{ exercise.downloads }}
</span>
</div>
<ng-template #helpForDownloads> {{ 'exercise.details.downloads' | translate }}</ng-template>
</div>
<!-- modal views end-->
<div *ngIf="exercise.downloads >= 0" class="positionRating">
<div [ngbTooltip]="helpForDownloads" style="float: left">
<fa-icon icon="download"></fa-icon>
</div>
<div class="star-container">
<span>
{{ exercise.downloads }}
</span>
</div>
<ng-template #helpForDownloads> {{ 'exercise.details.downloads' | translate }}</ng-template>
</div>
<!-- modal views end-->
<div *ngIf="exercise.numberOfWatchlistEntries >= 0" class="positionRating">
<div [ngbTooltip]="helpForWatchlists" style="float: left">
<fa-icon icon="star"></fa-icon>
</div>
<div class="star-container">
<span>
{{ exercise.numberOfWatchlistEntries }}
</span>
</div>
<ng-template #helpForWatchlists> {{ 'exercise.details.watchlists' | translate }}</ng-template>
</div>
<div *ngIf="exercise.numberOfWatchlistEntries >= 0" class="positionRating">
<div [ngbTooltip]="helpForWatchlists" style="float: left">
<fa-icon icon="star"></fa-icon>
</div>
<div class="star-container">
<span>
{{ exercise.numberOfWatchlistEntries }}
</span>
</div>
<ng-template #helpForWatchlists> {{ 'exercise.details.watchlists' | translate }}</ng-template>
</div>
<!-- modal bookmark-->
<div style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px">
<div style="float: left">
<p class="card-text" jhiTranslate="exercise.details.bookmark"></p>
</div>
<div class="form-check" style="float: right; padding-right: 10px" placement="right">
<input
class="form-check-input"
type="checkbox"
[checked]="isOnCurrentWatchlist(exercise)"
(change)="handleForCurrentWatchlist(exercise)"
value=""
id="modal-defaultCheck1"
/>
<label class="form-check-label" for="modal-defaultCheck1"></label>
</div>
</div>
<!-- modal bookmark end-->
<!-- modal bookmark-->
<div style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px">
<div style="float: left">
<p class="card-text" jhiTranslate="exercise.details.bookmark"></p>
</div>
<div class="form-check" style="float: right; padding-right: 10px" placement="right">
<input
class="form-check-input"
type="checkbox"
[checked]="isOnCurrentWatchlist(exercise)"
(change)="handleForCurrentWatchlist(exercise)"
value=""
id="modal-defaultCheck1"
/>
<label class="form-check-label" for="modal-defaultCheck1"></label>
</div>
</div>
<!-- modal bookmark end-->
<div *ngIf="exercise.originalResult.file.parentId" style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px">
<ng-template #helpToParent data-container="body"> {{ 'exercise.help.toParent' | translate }} </ng-template>
<fa-icon
style="padding: 5px 0px 0px 5px; float: left"
[ngbTooltip]="helpToParent"
container="body"
[icon]="treeIcon"
(click)="toParent(exercise.originalResult.file.parentId)"
></fa-icon>
</div>
<div *ngIf="exercise.originalResult.file.parentId" style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px">
<ng-template #helpToParent data-container="body"> {{ 'exercise.help.toParent' | translate }} </ng-template>
<fa-icon
style="padding: 5px 0px 0px 5px; float: left"
[ngbTooltip]="helpToParent"
container="body"
[icon]="treeIcon"
(click)="toParent(exercise.originalResult.file.parentId)"
></fa-icon>
</div>
<button
*ngIf="hasChildren()"
type="button"
class="btn btn-outline-secondary"
(click)="searchChildren(exercise.originalResult.exerciseId)"
data-dismiss="modal"
style="display: block; margin-bottom: 5px"
jhiTranslate="exercise.details.allExercises"
></button>
<button
type="button"
class="btn btn-outline-secondary"
style="display: block"
(click)="openLink(exercise.gitlabURL)"
jhiTranslate="exercise.details.git"
></button>
<button
*ngIf="hasChildren()"
type="button"
class="btn btn-outline-secondary"
(click)="searchChildren(exercise.originalResult.exerciseId)"
data-dismiss="modal"
style="display: block; margin-bottom: 5px"
jhiTranslate="exercise.details.allExercises"
></button>
<button
type="button"
class="btn btn-outline-secondary"
style="display: block"
(click)="openLink(exercise.gitlabURL)"
jhiTranslate="exercise.details.git"
></button>
<button
type="button"
class="btn btn-outline-secondary"
style="margin-top: 20px"
data-toggle="modal"
data-target="#mdModal"
(click)="selectREADME()"
>
README
</button>
</div>
<button
type="button"
class="btn btn-outline-secondary"
style="margin-top: 20px"
data-toggle="modal"
data-target="#mdModal"
(click)="selectREADME()"
>
README
</button>
</div>
<jhi-exercise-metadata class="col-sm-12 col-md-12 col-lg-6" [exercise]="exercise"> </jhi-exercise-metadata>
</div>
<div class="row">
<div class="col-12">
<p style="text-align: left; margin-top: 20px"><strong jhiTranslate="exercise.export.export"></strong></p>
<hr />
</div>
<div class="col-6">
<span>
<a
class="btn btn-outline-secondary"
role="button"
aria-pressed="true"
style="float: left; margin-right: 5px; margin-top: 5px"
(click)="download()"
jhiTranslate="exercise.export.download"
></a>
<label style="padding-top: 10px" for="withChildren">
{{ 'exercise.details.withChildren' | translate }}
<input type="checkbox" [hidden]="false" [(ngModel)]="downloadWithChildren" id="withChildren" />
</label>
</span>
</div>
<div class="col-6" *ngFor="let action of exercise.originalResult.supportedActions">
<a
class="btn btn-outline-secondary positionAction col-6"
role="button"
aria-pressed="true"
(click)="startAction(action, exercise)"
>{{ action.commandName }}</a
>
</div>
<div class="col-6" placement="bottom">
<span [ngbTooltip]="helpComingSoon">
<button
*ngIf="hasChildren()"
type="button"
class="btn btn-outline-secondary positionAction"
jhiTranslate="exercise.export.latex"
disabled
></button>
</span>
</div>
</div>
</div>
<jhi-exercise-metadata class="col-sm-12 col-md-12 col-lg-6" [exercise]="exercise"> </jhi-exercise-metadata>
</div>
<div class="row">
<div class="col-12">
<p style="text-align: left; margin-top: 20px"><strong jhiTranslate="exercise.export.export"></strong></p>
<hr />
</div>
<div class="col-6">
<span>
<a
class="btn btn-outline-secondary"
role="button"
aria-pressed="true"
style="float: left; margin-right: 5px; margin-top: 5px"
(click)="download()"
jhiTranslate="exercise.export.download"
></a>
<label style="padding-top: 10px" for="withChildren">
{{ 'exercise.details.withChildren' | translate }}
<input type="checkbox" [hidden]="false" [(ngModel)]="downloadWithChildren" id="withChildren" />
</label>
</span>
</div>
<div class="col-6" *ngFor="let action of exercise.originalResult.supportedActions">
<a class="btn btn-outline-secondary positionAction col-6" role="button" aria-pressed="true" (click)="startAction(action, exercise)">{{
action.commandName
}}</a>
</div>
<div class="col-6" placement="bottom">
<span [ngbTooltip]="helpComingSoon">
<button
*ngIf="hasChildren()"
type="button"
class="btn btn-outline-secondary positionAction"
jhiTranslate="exercise.export.latex"
disabled
></button>
</span>
</div>
</div>
</div>
<img *ngIf="exercise"
class="card-img-top col-3"
src="{{ exercise.imageURL }}"
alt="exercise image"
(error)="correctImageURL($event)"
style="height: auto; float: left"
/>
<h4 *ngIf="exercise" class="modal-title">{{ exercise.title }}</h4>
<img
*ngIf="exercise"
class="card-img-top col-3"
src="{{ exercise.imageURL }}"
alt="exercise image"
(error)="correctImageURL($event)"
style="height: auto; float: left"
/>
<h4 *ngIf="exercise" class="modal-title">{{ exercise.title }}</h4>
.modal-title {
padding-top: 5px;
}
......@@ -5,7 +5,12 @@ import { MarkdownModule, MarkedOptions } from 'ngx-markdown';
import { MarkDownViewerComponent } from '../exercise/markDownViewer/markDownViewer.component';
import { ExerciseCardComponent } from './exercise-card/exercise-card.component';
import { ExerciseDetailsModalComponent, ExerciseDetailsNonModalComponent, ExerciseHeaderComponent, ExerciseBodyComponent } from './exercise-details/exercise-details.component';
import {
ExerciseDetailsModalComponent,
ExerciseDetailsNonModalComponent,
ExerciseHeaderComponent,
ExerciseBodyComponent,
} from './exercise-details/exercise-details.component';
import { ExerciseMetadataItemComponent } from './exercise-details/exercise-metadata/exercise-metadata-item/exercise-metadata-item.component';
import { ExerciseMetadataComponent } from './exercise-details/exercise-metadata/exercise-metadata.component';
......@@ -31,7 +36,8 @@ import { ExerciseMetadataComponent } from './exercise-details/exercise-metadata/
ExerciseDetailsModalComponent,
ExerciseMetadataComponent,
ExerciseMetadataItemComponent,
ExerciseHeaderComponent, ExerciseBodyComponent,
ExerciseHeaderComponent,
ExerciseBodyComponent,
ExerciseDetailsNonModalComponent,
MarkDownViewerComponent,
],
......
......@@ -2,8 +2,6 @@
<div class="exercise-container">
<div *ngIf="errorMessage" jhiTranslate="{{ errorMessage }}" [translateValues]="{ param: exerciseId }">Fehler:</div>
<jhi-exercise-modal-details [exercise]="exercise"></jhi-exercise-modal-details>
<jhi-exercise-card class="card-container col-12 col-lg-6 col-xl-4" [exercise]="exercise" [autoOpenDetails]="true"> </jhi-exercise-card>
<jhi-exercise-nonmodal-details [exercise]="exercise"></jhi-exercise-nonmodal-details>
</div>
</div>
.exercise-container {
padding: 20px;
padding: 20px 20px 20px 100px;
vertical-align: center;
}
......@@ -19,7 +19,7 @@ export class ExerciseResolve implements Resolve<String> {
}
export const exerciseRoutes = {
path: 'exercise',
path: 'item',
children: [
{
path: '**',
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment