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

Skip to content
Snippets Groups Projects
Commit 1101837c authored by Michael Breu's avatar Michael Breu :speech_balloon:
Browse files

Intermediate commit: First work on bookmark page

parent 23aeb22f
No related merge requests found
Showing
with 605 additions and 2 deletions
...@@ -30,6 +30,10 @@ const LAYOUT_ROUTES = [navbarRoute, SEARCH_ROUTE, ...errorRoute]; ...@@ -30,6 +30,10 @@ const LAYOUT_ROUTES = [navbarRoute, SEARCH_ROUTE, ...errorRoute];
path: 'search', path: 'search',
loadChildren: () => import('app/search/search.module').then(m => m.SearchModule), loadChildren: () => import('app/search/search.module').then(m => m.SearchModule),
}, },
{
path: 'bookmarks',
loadChildren: () => import('app/bookmarks/bookmarks.module').then(m => m.BookmarskModule),
},
...LAYOUT_ROUTES, ...LAYOUT_ROUTES,
], ],
{ enableTracing: DEBUG_INFO_ENABLED } { enableTracing: DEBUG_INFO_ENABLED }
......
<div>
<h2 id="page-heading">
<span jhiTranslate="gitsearchApp.userWatchList.home.title">User Watch Lists</span>
<button id="jh-create-entity" class="btn btn-primary float-right jh-create-entity create-user-watch-list" [routerLink]="['/user-watch-list/new']">
<fa-icon icon="plus"></fa-icon>
<span class="hidden-sm-down" jhiTranslate="gitsearchApp.userWatchList.home.createLabel">
Create a new User Watch List
</span>
</button>
</h2>
<jhi-alert-error></jhi-alert-error>
<jhi-alert></jhi-alert>
<div class="row">
<div class="col-sm-12">
<form name="searchForm" class="form-inline">
<div class="input-group w-100 mt-3">
<input type="text" class="form-control" [(ngModel)]="currentSearch" id="currentSearch" name="currentSearch" placeholder="{{ 'gitsearchApp.userWatchList.home.search' | translate }}">
<button class="input-group-append btn btn-info" (click)="search(currentSearch)">
<fa-icon icon="search"></fa-icon>
</button>
<button class="input-group-append btn btn-danger" (click)="search('')" *ngIf="currentSearch">
<fa-icon icon="trash-alt"></fa-icon>
</button>
</div>
</form>
</div>
</div>
<div class="alert alert-warning" id="no-result" *ngIf="userWatchLists?.length === 0">
<span jhiTranslate="gitsearchApp.userWatchList.home.notFound">No userWatchLists found</span>
</div>
<div class="table-responsive" id="entities" *ngIf="userWatchLists && userWatchLists.length > 0">
<table class="table table-striped" aria-describedby="page-heading">
<thead>
<tr jhiSort [(predicate)]="predicate" [(ascending)]="ascending" [callback]="reset.bind(this)">
<th scope="col" jhiSortBy="id"><span jhiTranslate="global.field.id">ID</span> <fa-icon icon="sort"></fa-icon></th>
<th scope="col" jhiSortBy="name"><span jhiTranslate="gitsearchApp.userWatchList.name">Name</span> <fa-icon icon="sort"></fa-icon></th>
<th scope="col" jhiSortBy="userIdLogin"><span jhiTranslate="gitsearchApp.userWatchList.userId">User Id</span> <fa-icon icon="sort"></fa-icon></th>
<th scope="col"></th>
</tr>
</thead>
<tbody infinite-scroll (scrolled)="loadPage(page + 1)" [infiniteScrollDisabled]="page >= links['last']" [infiniteScrollDistance]="0">
<tr *ngFor="let userWatchList of userWatchLists ;trackBy: trackId">
<td><a [routerLink]="['/user-watch-list', userWatchList.id, 'view']">{{ userWatchList.id }}</a></td>
<td>{{ userWatchList.name }}</td>
<td>
{{ userWatchList.userIdLogin }}
</td>
<td class="text-right">
<div class="btn-group">
<button type="submit"
[routerLink]="['/user-watch-list', userWatchList.id, 'view']"
class="btn btn-info btn-sm">
<fa-icon icon="eye"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
</button>
<button type="submit"
[routerLink]="['/user-watch-list', userWatchList.id, 'edit']"
class="btn btn-primary btn-sm">
<fa-icon icon="pencil-alt"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit" (click)="delete(userWatchList)"
class="btn btn-danger btn-sm">
<fa-icon icon="times"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
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 { 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';
@Component({
selector: 'jhi-bookmarks',
templateUrl: './bookmarks.component.html',
})
export class BookmarkComponent implements OnInit, OnDestroy {
userWatchLists: IUserWatchList[];
eventSubscriber?: Subscription;
itemsPerPage: number;
links: any;
page: number;
predicate: string;
ascending: boolean;
currentSearch: string;
constructor(
protected userWatchListService: UserWatchListService,
protected eventManager: JhiEventManager,
protected modalService: NgbModal,
protected parseLinks: JhiParseLinks,
protected activatedRoute: ActivatedRoute
) {
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
.search({
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
.query({
page: this.page,
size: this.itemsPerPage,
sort: this.sort(),
})
.subscribe((res: HttpResponse<IUserWatchList[]>) => this.paginateUserWatchLists(res.body, res.headers));
}
reset(): void {
this.page = 0;
this.userWatchLists = [];
this.loadAll();
}
loadPage(page: number): void {
this.page = page;
this.loadAll();
}
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());
}
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;
}
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]);
}
}
}
}
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { GitSearchV2SharedModule } from 'app/shared/shared.module';
import { BookmarkComponent } from './bookmarks.component';
import { UserWatchListDetailComponent } from './user-watch-list-detail.component';
import { UserWatchListUpdateComponent } from './user-watch-list-update.component';
import { UserWatchListDeleteDialogComponent } from './user-watch-list-delete-dialog.component';
import { bookmarksRoute } from './bookmarks.route';
@NgModule({
imports: [GitSearchV2SharedModule, RouterModule.forChild(bookmarksRoute)],
declarations: [BookmarkComponent, UserWatchListDetailComponent, UserWatchListUpdateComponent, UserWatchListDeleteDialogComponent],
entryComponents: [UserWatchListDeleteDialogComponent],
})
export class BookmarskModule {}
import { Injectable } from '@angular/core';
import { HttpResponse } from '@angular/common/http';
import { Resolve, ActivatedRouteSnapshot, Routes, Router } from '@angular/router';
import { Observable, of, EMPTY } from 'rxjs';
import { flatMap } from 'rxjs/operators';
import { Authority } from 'app/shared/constants/authority.constants';
import { UserRouteAccessService } from 'app/core/auth/user-route-access-service';
import { IUserWatchList, UserWatchList } from 'app/shared/model/user-watch-list.model';
import { UserWatchListService } from 'app/entities/user-watch-list/user-watch-list.service';
import { BookmarkComponent } from './bookmarks.component';
import { UserWatchListDetailComponent } from './user-watch-list-detail.component';
import { UserWatchListUpdateComponent } from './user-watch-list-update.component';
@Injectable({ providedIn: 'root' })
export class BookmarksResolve implements Resolve<IUserWatchList> {
constructor(private service: UserWatchListService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot): Observable<IUserWatchList> | Observable<never> {
const id = route.params['id'];
if (id) {
return this.service.find(id).pipe(
flatMap((userWatchList: HttpResponse<UserWatchList>) => {
if (userWatchList.body) {
return of(userWatchList.body);
} else {
this.router.navigate(['404']);
return EMPTY;
}
})
);
}
return of(new UserWatchList());
}
}
export const bookmarksRoute: Routes = [
{
path: '',
component: BookmarkComponent,
data: {
authorities: [Authority.USER],
pageTitle: 'global.menu.bookmarks',
},
canActivate: [UserRouteAccessService],
},
{
path: ':id/view',
component: UserWatchListDetailComponent,
resolve: {
userWatchList: BookmarksResolve,
},
data: {
authorities: [Authority.USER],
pageTitle: 'gitsearchApp.userWatchList.home.title',
},
canActivate: [UserRouteAccessService],
},
{
path: 'new',
component: UserWatchListUpdateComponent,
resolve: {
userWatchList: BookmarksResolve,
},
data: {
authorities: [Authority.USER],
pageTitle: 'gitsearchApp.userWatchList.home.title',
},
canActivate: [UserRouteAccessService],
},
{
path: ':id/edit',
component: UserWatchListUpdateComponent,
resolve: {
userWatchList: BookmarksResolve,
},
data: {
authorities: [Authority.USER],
pageTitle: 'gitsearchApp.userWatchList.home.title',
},
canActivate: [UserRouteAccessService],
},
];
<form *ngIf="userWatchList" name="deleteForm" (ngSubmit)="confirmDelete(userWatchList?.id!)">
<div class="modal-header">
<h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"
(click)="cancel()">&times;</button>
</div>
<div class="modal-body">
<jhi-alert-error></jhi-alert-error>
<p id="jhi-delete-userWatchList-heading" jhiTranslate="gitsearchApp.userWatchList.delete.question" [translateValues]="{ id: userWatchList.id }">Are you sure you want to delete this User Watch List?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()">
<fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
</button>
<button id="jhi-confirm-delete-userWatchList" type="submit" class="btn btn-danger">
<fa-icon icon="times"></fa-icon>&nbsp;<span jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</form>
import { Component } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { JhiEventManager } from 'ng-jhipster';
import { IUserWatchList } from 'app/shared/model/user-watch-list.model';
import { UserWatchListService } from 'app/entities/user-watch-list/user-watch-list.service';
@Component({
templateUrl: './user-watch-list-delete-dialog.component.html',
})
export class UserWatchListDeleteDialogComponent {
userWatchList?: IUserWatchList;
constructor(
protected userWatchListService: UserWatchListService,
public activeModal: NgbActiveModal,
protected eventManager: JhiEventManager
) {}
cancel(): void {
this.activeModal.dismiss();
}
confirmDelete(id: number): void {
this.userWatchListService.delete(id).subscribe(() => {
this.eventManager.broadcast('userWatchListListModification');
this.activeModal.close();
});
}
}
<div class="row justify-content-center">
<div class="col-8">
<div *ngIf="userWatchList">
<h2><span jhiTranslate="gitsearchApp.userWatchList.detail.title">User Watch List</span> {{ userWatchList.id }}</h2>
<hr>
<jhi-alert-error></jhi-alert-error>
<dl class="row-md jh-entity-details">
<dt><span jhiTranslate="gitsearchApp.userWatchList.name">Name</span></dt>
<dd>
<span>{{ userWatchList.name }}</span>
</dd>
<dt><span jhiTranslate="gitsearchApp.userWatchList.userId">User Id</span></dt>
<dd>
{{ userWatchList.userIdLogin }}
</dd>
</dl>
<button type="submit"
(click)="previousState()"
class="btn btn-info">
<fa-icon icon="arrow-left"></fa-icon>&nbsp;<span jhiTranslate="entity.action.back">Back</span>
</button>
<button type="button"
[routerLink]="['/user-watch-list', userWatchList.id, 'edit']"
class="btn btn-primary">
<fa-icon icon="pencil-alt"></fa-icon>&nbsp;<span jhiTranslate="entity.action.edit">Edit</span>
</button>
</div>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { IUserWatchList } from 'app/shared/model/user-watch-list.model';
@Component({
selector: 'jhi-user-watch-list-detail',
templateUrl: './user-watch-list-detail.component.html',
})
export class UserWatchListDetailComponent implements OnInit {
userWatchList: IUserWatchList | null = null;
constructor(protected activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
this.activatedRoute.data.subscribe(({ userWatchList }) => (this.userWatchList = userWatchList));
}
previousState(): void {
window.history.back();
}
}
<div class="row justify-content-center">
<div class="col-8">
<form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm">
<h2 id="jhi-user-watch-list-heading" jhiTranslate="gitsearchApp.userWatchList.home.createOrEditLabel">Create or edit a User Watch List</h2>
<div>
<jhi-alert-error></jhi-alert-error>
<div class="form-group" [hidden]="!editForm.get('id')!.value">
<label for="id" jhiTranslate="global.field.id">ID</label>
<input type="text" class="form-control" id="id" name="id" formControlName="id" readonly />
</div>
<div class="form-group">
<label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.name" for="field_name">Name</label>
<input type="text" class="form-control" name="name" id="field_name"
formControlName="name"/>
<div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)">
<small class="form-text text-danger"
*ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required">
This field is required.
</small>
<small class="form-text text-danger"
*ngIf="editForm.get('name')?.errors?.minlength" jhiTranslate="entity.validation.minlength" [translateValues]="{ min: 1 }">
This field is required to be at least 1 characters.
</small>
</div>
</div>
<div class="form-group">
<label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.userId" for="field_userId">User Id</label>
<select class="form-control" id="field_userId" name="userId" formControlName="userIdId">
<option *ngIf="!editForm.get('userIdId')!.value" [ngValue]="null" selected></option>
<option [ngValue]="userOption.id" *ngFor="let userOption of users; trackBy: trackById">{{ userOption.login }}</option>
</select>
</div>
<div *ngIf="editForm.get('userIdId')!.invalid && (editForm.get('userIdId')!.dirty || editForm.get('userIdId')!.touched)">
<small class="form-text text-danger"
*ngIf="editForm.get('userIdId')?.errors?.required" jhiTranslate="entity.validation.required">
This field is required.
</small>
</div>
</div>
<div>
<button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()">
<fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
</button>
<button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary">
<fa-icon icon="save"></fa-icon>&nbsp;<span jhiTranslate="entity.action.save">Save</span>
</button>
</div>
</form>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import { HttpResponse } from '@angular/common/http';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FormBuilder, Validators } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { IUserWatchList, UserWatchList } from 'app/shared/model/user-watch-list.model';
import { UserWatchListService } from 'app/entities/user-watch-list/user-watch-list.service';
import { IUser } from 'app/core/user/user.model';
import { UserService } from 'app/core/user/user.service';
@Component({
selector: 'jhi-user-watch-list-update',
templateUrl: './user-watch-list-update.component.html',
})
export class UserWatchListUpdateComponent implements OnInit {
isSaving = false;
users: IUser[] = [];
editForm = this.fb.group({
id: [],
name: [null, [Validators.required, Validators.minLength(1)]],
userIdId: [null, Validators.required],
});
constructor(
protected userWatchListService: UserWatchListService,
protected userService: UserService,
protected activatedRoute: ActivatedRoute,
private fb: FormBuilder
) {}
ngOnInit(): void {
this.activatedRoute.data.subscribe(({ userWatchList }) => {
this.updateForm(userWatchList);
this.userService.query().subscribe((res: HttpResponse<IUser[]>) => (this.users = res.body || []));
});
}
updateForm(userWatchList: IUserWatchList): void {
this.editForm.patchValue({
id: userWatchList.id,
name: userWatchList.name,
userIdId: userWatchList.userIdId,
});
}
previousState(): void {
window.history.back();
}
save(): void {
this.isSaving = true;
const userWatchList = this.createFromForm();
if (userWatchList.id !== undefined) {
this.subscribeToSaveResponse(this.userWatchListService.update(userWatchList));
} else {
this.subscribeToSaveResponse(this.userWatchListService.create(userWatchList));
}
}
private createFromForm(): IUserWatchList {
return {
...new UserWatchList(),
id: this.editForm.get(['id'])!.value,
name: this.editForm.get(['name'])!.value,
userIdId: this.editForm.get(['userIdId'])!.value,
};
}
protected subscribeToSaveResponse(result: Observable<HttpResponse<IUserWatchList>>): void {
result.subscribe(
() => this.onSaveSuccess(),
() => this.onSaveError()
);
}
protected onSaveSuccess(): void {
this.isSaving = false;
this.previousState();
}
protected onSaveError(): void {
this.isSaving = false;
}
trackById(index: number, item: IUser): any {
return item.id;
}
}
...@@ -109,6 +109,19 @@ ...@@ -109,6 +109,19 @@
</span> </span>
</div> </div>
<!-- End search --> <!-- End search -->
<!-- Bookmarks -->
<div class="nav-item" >
<span class="nav-link">
<a routerLink="/bookmarks">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bookmarks" viewBox="0 0 16 16">
<path d="M2 4a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v11.5a.5.5 0 0 1-.777.416L7 13.101l-4.223 2.815A.5.5 0 0 1 2 15.5V4zm2-1a1 1 0 0 0-1 1v10.566l3.723-2.482a.5.5 0 0 1 .554 0L11 14.566V4a1 1 0 0 0-1-1H4z"/>
<path d="M4.268 1H12a1 1 0 0 1 1 1v11.768l.223.148A.5.5 0 0 0 14 13.5V2a2 2 0 0 0-2-2H6a2 2 0 0 0-1.732 1z"/>
</svg>
<span jhiTranslate="global.menu.bookmarks"></span>
</a>
</span>
</div>
<!-- End Bookmarks -->
<!-- Menu Entities --> <!-- Menu Entities -->
<!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here --> <!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here -->
......
...@@ -40,7 +40,8 @@ ...@@ -40,7 +40,8 @@
"jhipster-needle-menu-add-admin-element": "JHipster will add additional menu entries here (do not translate!)" "jhipster-needle-menu-add-admin-element": "JHipster will add additional menu entries here (do not translate!)"
}, },
"language": "Sprache", "language": "Sprache",
"search": "Suche" "search": "Suche",
"bookmarks": "Lesezeichen"
}, },
"form": { "form": {
"username.label": "Benutzername", "username.label": "Benutzername",
......
...@@ -40,7 +40,8 @@ ...@@ -40,7 +40,8 @@
"jhipster-needle-menu-add-admin-element": "JHipster will add additional menu entries here (do not translate!)" "jhipster-needle-menu-add-admin-element": "JHipster will add additional menu entries here (do not translate!)"
}, },
"language": "Language", "language": "Language",
"search": "Search" "search": "Search",
"bookmarks": "Bookmarks"
}, },
"form": { "form": {
"username.label": "Username", "username.label": "Username",
......
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