Added tags system.
This commit is contained in:
parent
af1d853fff
commit
aa20ce04b1
@ -13,13 +13,13 @@
|
||||
<div class="row">
|
||||
<div class="col-md-8 offset-md-2 centercontents">
|
||||
<div id="topmenubuttons">
|
||||
<div class="btn-group mx-auto" role="group" aria-label="Basic example">
|
||||
<div class="btn-group mx-auto" role="group">
|
||||
<!-- <button type="button" class="btn btn-secondary">Left</button> -->
|
||||
<!-- <button type="button" class="btn btn-secondary">Middle</button> -->
|
||||
<!-- <button type="button" class="btn btn-secondary">Right</button> -->
|
||||
<a routerLink="/home"><i class="text-secondary fa fa-home fa-fw fa-2x" tooltip="Huis" placement="bottom" aria-hidden="true"></i></a>
|
||||
<a routerLink="/posts"><i class="text-secondary fa fa-sticky-note fa-fw fa-2x" tooltip="Posts" placement="bottom" aria-hidden="true"></i></a>
|
||||
<a routerLink="/cv"><i class="text-secondary fa fa-id-badge fa-fw fa-2x" tooltip="Curriculum Vitae" placement="bottom" aria-hidden="true"></i></a>
|
||||
<a routerLink="/home"><i class="fa fa-home fa-fw fa-2x" tooltip="Huis" placement="bottom" aria-hidden="true"></i></a>
|
||||
<a routerLink="/posts"><i class="fa fa-sticky-note fa-fw fa-2x" tooltip="Posts" placement="bottom" aria-hidden="true"></i></a>
|
||||
<a routerLink="/cv"><i class="fa fa-id-badge fa-fw fa-2x" tooltip="Curriculum Vitae" placement="bottom" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -41,3 +41,13 @@
|
||||
border-top: 1px solid black;
|
||||
margin: 35px 30px 25px 30px;
|
||||
}
|
||||
|
||||
#topmenubuttons {
|
||||
a {
|
||||
color: lightgrey;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: darkorange;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,9 @@ import { PosttypepipePipe } from './pipes/posttypepipe.pipe';
|
||||
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
||||
import {SimpledatePipe} from './pipes/simpledate.pipe';
|
||||
import { PosttagComponent } from './components/post/posttag/posttag.component';
|
||||
import { ButtonsModule } from 'ngx-bootstrap/buttons';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {StateService} from './services/state.service';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -30,9 +33,11 @@ import { PosttagComponent } from './components/post/posttag/posttag.component';
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
HttpClientModule,
|
||||
TooltipModule.forRoot()
|
||||
FormsModule,
|
||||
TooltipModule.forRoot(),
|
||||
ButtonsModule.forRoot()
|
||||
],
|
||||
providers: [DataloaderService],
|
||||
providers: [DataloaderService, StateService],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
.blocktitle {
|
||||
text-align: center;
|
||||
font-size: 150%;
|
||||
border-bottom: 1px dotted black;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
margin: 0px 30px 0px 30px;
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ export class CvComponent implements OnInit {
|
||||
.setLanguage("nl")
|
||||
.setEmployer('Universiteit Gent')
|
||||
.setTitle('Doctor in de ingenieurswetenschappen: computerwetenschappen')
|
||||
.setDescription('Het doctoraatswerk getiteld "XPath-gebaseerde informatie-extractie" behandelt het extraheren van informatie uit semi-gestructureerde documenten zoals HTML, gebruik makend van XPath.')
|
||||
.setDescription('Manuscript: "XPath-gebaseerde informatie-extractie" - informatie extraheren uit semi-gestructureerde documenten zoals HTML, gebruik makend van XPath')
|
||||
.setFromYear(2010)
|
||||
.setToYear(2017)
|
||||
.setIconName("assets/images/ugent-icon.png"),
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div class="post-tags">
|
||||
<div class="post-tag" *ngFor="let tag of post.tags">
|
||||
<app-posttag [tag] = tag></app-posttag>
|
||||
<app-posttag [tag]=tag [class.highlight]="isActiveTag(tag)"></app-posttag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -41,3 +41,12 @@
|
||||
padding-right: 25px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.post-tag {
|
||||
|
||||
color: lightgrey;
|
||||
|
||||
.highlight {
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {Component, OnInit, Input, ViewChild, ElementRef} from '@angular/core';
|
||||
import { Post } from 'app/model/post';
|
||||
import { DataloaderService } from 'app/services/dataloader.service';
|
||||
import {StateService} from '../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-post',
|
||||
@ -12,7 +13,7 @@ export class PostComponent implements OnInit {
|
||||
@Input() post: Post;
|
||||
@ViewChild('htmlcontainer') htmlContainer: ElementRef;
|
||||
|
||||
constructor(private dataloaderService: DataloaderService) { }
|
||||
constructor(private dataloaderService: DataloaderService, private stateService:StateService) { }
|
||||
|
||||
ngOnInit() {
|
||||
// TODO load the relevant HTML file!
|
||||
@ -30,4 +31,8 @@ export class PostComponent implements OnInit {
|
||||
|
||||
console.log('PostComponent.ngOnInit is done.');
|
||||
}
|
||||
|
||||
isActiveTag(tag:string):boolean {
|
||||
return this.stateService.isActiveTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div [ngSwitch]="tag" title="{{tag}}">
|
||||
<div [ngSwitch]="tag" [class.highlight]="highlight">
|
||||
<ng-template [ngSwitchCase]= "'tech'"><i class="fa fa-wrench"></i></ng-template>
|
||||
<ng-template [ngSwitchCase]= "'project'"><i class="fa fa-map"></i></ng-template>
|
||||
<ng-template ngSwitchDefault><i class="fa fa-question-circle"></i></ng-template>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {Post} from '../../../model/post';
|
||||
import {StateService} from '../../../services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-posttag',
|
||||
@ -9,6 +10,7 @@ import {Post} from '../../../model/post';
|
||||
export class PosttagComponent implements OnInit {
|
||||
|
||||
@Input() tag: string;
|
||||
@Input() highlight: boolean;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
@ -1,3 +1,12 @@
|
||||
<div>
|
||||
<app-post *ngFor='let post of posts' [post]="post"></app-post>
|
||||
<div id="tag-filter-buttons-container">
|
||||
<div class="btn-group tag-filter-buttons">
|
||||
<label class="btn btn-primary" *ngFor="let tag of tags" (click)="toggleTag(tag)" [class.active]="isActiveTag(tag)"
|
||||
data-toggle="button" title="Toggle {{tag}} posts">
|
||||
<app-posttag [tag]=tag></app-posttag>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<app-post *ngFor='let post of postsToDisplay()' [post]="post"></app-post>
|
||||
</div>
|
||||
|
||||
26
src/app/components/posts/posts.component.scss
Normal file
26
src/app/components/posts/posts.component.scss
Normal file
@ -0,0 +1,26 @@
|
||||
#tag-filter-buttons-container {
|
||||
text-align: center;
|
||||
margin-top: -16pt;
|
||||
margin-bottom: 12pt;
|
||||
|
||||
.btn.active {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
color: darkorange;
|
||||
}
|
||||
|
||||
.btn.active:hover {
|
||||
color: darkgoldenrod;
|
||||
}
|
||||
|
||||
.btn {
|
||||
color: lightgrey;
|
||||
background-color: white;
|
||||
border: none;
|
||||
padding: 0pt 3pt;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import { DataloaderService } from 'app/services/dataloader.service';
|
||||
import {StateService} from '../../services/state.service';
|
||||
import { Post } from '../../model/post';
|
||||
|
||||
import 'rxjs/add/operator/map';
|
||||
@ -11,7 +12,7 @@ import 'rxjs/add/operator/distinct';
|
||||
@Component({
|
||||
selector: 'app-posts',
|
||||
templateUrl: './posts.component.html',
|
||||
styleUrls: ['./posts.component.css']
|
||||
styleUrls: ['./posts.component.scss']
|
||||
})
|
||||
export class PostsComponent implements OnInit, OnDestroy {
|
||||
|
||||
@ -21,8 +22,9 @@ export class PostsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
posts:Post[];
|
||||
tags = new Array<string>();
|
||||
|
||||
constructor(private dataloaderService:DataloaderService) { }
|
||||
constructor(private dataloaderService:DataloaderService, private stateService:StateService) { }
|
||||
|
||||
ngOnInit() {
|
||||
console.log('PostsComponent ngOnInit()');
|
||||
@ -32,8 +34,18 @@ export class PostsComponent implements OnInit, OnDestroy {
|
||||
//TODO fix this!!!
|
||||
posts2.subscribe(p => {
|
||||
this.posts = p;
|
||||
console.log('dataloaderService.getPosts() call got back! '+p);
|
||||
console.log('posts size: '+p.length);
|
||||
|
||||
//figure out the different tags so we can filter on them
|
||||
let temptags = new Array<string>();
|
||||
this.posts.forEach(p=>p.tags.forEach(t=>temptags.push(t)));
|
||||
console.log(temptags);
|
||||
//copy the temptags into the tags array, don't include duplicates
|
||||
temptags.forEach(tt=> {
|
||||
if(this.tags.indexOf(tt)==-1)
|
||||
this.tags.push(tt)
|
||||
});
|
||||
//sort the array
|
||||
this.tags.sort((a,b)=>a.localeCompare(b));
|
||||
});
|
||||
console.log('PostsComponent ngOnInit() is done');
|
||||
}
|
||||
@ -41,4 +53,26 @@ export class PostsComponent implements OnInit, OnDestroy {
|
||||
filterOnType(type:String): void {
|
||||
|
||||
}
|
||||
|
||||
postsToDisplay():Post[] {
|
||||
//console.log('postsToDisplay called');
|
||||
let res = new Array<Post>();
|
||||
if(this.posts == null)
|
||||
return res;
|
||||
for(let post of this.posts) {
|
||||
if(this.stateService.shouldDisplay(post))
|
||||
res.push(post);
|
||||
}
|
||||
//console.log('displaying: '+res.length);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
toggleTag(tag: string) {
|
||||
this.stateService.toggleTag(tag);
|
||||
}
|
||||
|
||||
isActiveTag(tag: string) : boolean {
|
||||
return this.stateService.isActiveTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ export class DataloaderService {
|
||||
const url = 'assets/post/' + id + '/full.html';
|
||||
|
||||
// console.log('fetching: '+url);
|
||||
console.log('getPost called: '+url);
|
||||
//console.log('getPost called: '+url);
|
||||
|
||||
return this.http.get(url, {responseType: 'text'});
|
||||
}
|
||||
|
||||
15
src/app/services/state.service.spec.ts
Normal file
15
src/app/services/state.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { StateService } from './state.service';
|
||||
|
||||
describe('StateService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [StateService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([StateService], (service: StateService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
||||
57
src/app/services/state.service.ts
Normal file
57
src/app/services/state.service.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {Post} from '../model/post';
|
||||
|
||||
@Injectable()
|
||||
export class StateService {
|
||||
|
||||
//this keeps track of which type is enabled / disabled
|
||||
tagFilter:any = [];
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
shouldDisplay(post:Post): boolean {
|
||||
//check whether all filters are true or false: that case, just show everything
|
||||
let foundTrue:boolean = false;
|
||||
let foundFalse:boolean = false;
|
||||
for(let tag of Object.keys(this.tagFilter)) {
|
||||
if(this.tagFilter[tag] === true)
|
||||
foundTrue = true;
|
||||
if(this.tagFilter[tag] === false)
|
||||
foundFalse = true;
|
||||
}
|
||||
// console.log('foundFalse: '+foundFalse);
|
||||
// console.log('foundTrue: '+foundTrue);
|
||||
if(!foundTrue && foundFalse)
|
||||
return true;
|
||||
if(!foundTrue && !foundFalse)
|
||||
//some weird case, just show everything
|
||||
return true;
|
||||
|
||||
//check whether the post should be displayed
|
||||
for(let tag of Object.keys(this.tagFilter)) {
|
||||
if(post.tags.indexOf(tag)!=-1 && this.tagFilter[tag]===true) {
|
||||
//found the tag and its filter is enabled
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
isActiveTag(tag:string):boolean {
|
||||
console.log('isActive');
|
||||
console.log(this.tagFilter);
|
||||
return this.tagFilter[tag]===true;
|
||||
}
|
||||
|
||||
toggleTag(tag: string) {
|
||||
console.log('toggle');
|
||||
console.log(this.tagFilter);
|
||||
if(this.tagFilter[tag]==null)
|
||||
this.tagFilter[tag] = true;
|
||||
else
|
||||
this.tagFilter[tag] = !this.tagFilter[tag];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user