Added tags system.

This commit is contained in:
Joachim Nielandt 2018-03-24 11:10:14 +01:00
parent af1d853fff
commit aa20ce04b1
17 changed files with 190 additions and 18 deletions

View File

@ -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>

View File

@ -41,3 +41,13 @@
border-top: 1px solid black;
margin: 35px 30px 25px 30px;
}
#topmenubuttons {
a {
color: lightgrey;
}
a:hover {
color: darkorange;
}
}

View File

@ -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 { }

View File

@ -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;
}

View File

@ -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"),

View File

@ -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>

View File

@ -41,3 +41,12 @@
padding-right: 25px;
text-align: justify;
}
.post-tag {
color: lightgrey;
.highlight {
color: grey;
}
}

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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() {
}

View File

@ -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>

View 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;
}
}

View File

@ -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);
}
}

View File

@ -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'});
}

View 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();
}));
});

View 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];
}
}