File
Description
Handles the creation of tags for blog posts
TODO Refactor behavior so it takes in an async post instead of making its own calls to the server
Metadata
| selector |
app-tags |
| styleUrls |
tags.component.scss |
| templateUrl |
tags.component.html |
Constructor
constructor(afs: AngularFirestore)
|
Methods
|
add
|
add(event: MatChipInputEvent)
|
|
Returns: void
|
|
remove
|
remove(tag: string)
|
Removes tags from the list
Returns: void
|
|
selected
|
selected(event: MatAutocompleteSelectedEvent)
|
Handles selection of autocomplete tag
Parameters :
-
event
Event when autocomplete option is selected
Returns: void
|
|
Private _filter
|
_filter(value: string)
|
Method to filter tags and make sure they're usable
Returns: string[]
|
|
Public getColor
|
getColor(tag: string)
|
|
Returns: string
|
|
addOnBlur
|
addOnBlur: boolean
|
Default value: true
|
|
alltags
|
alltags: string[]
|
|
filteredTags
|
filteredTags: Observable<string[]>
|
|
matAutocomplete
|
matAutocomplete: MatAutocomplete
|
|
Private postDoc
|
postDoc: any
|
|
removable
|
removable: boolean
|
Default value: true
|
|
selectable
|
selectable: boolean
|
Default value: true
|
|
separatorKeysCodes
|
separatorKeysCodes: number[]
|
|
visible
|
visible: boolean
|
Default value: true
|
import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {Component, ElementRef, ViewChild, Input, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms';
import {MatAutocompleteSelectedEvent, MatAutocomplete} from '@angular/material/autocomplete';
import {MatChipInputEvent} from '@angular/material/chips';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Post } from 'src/app/_models/post.model';
/**
* Handles the creation of tags for blog posts
* TODO Refactor behavior so it takes in an async post instead of making its own calls to the server
*/
@Component({
selector: 'app-tags',
templateUrl: './tags.component.html',
styleUrls: ['./tags.component.scss']
})
export class TagsComponent implements OnInit {
private postDoc: AngularFirestoreDocument<Post>; // Reference to post
visible = true;
selectable = true;
removable = true;
addOnBlur = true;
separatorKeysCodes: number[] = [ENTER, COMMA]; // Seperators for the tags
tagCtrl = new FormControl(); // Form CTRL for tags
filteredTags: Observable<string[]>;
tags: string[] = ['Machine Learning'];
// List of all the possible tags for autofill
alltags: string[] = ['Machine Learning', 'AI', 'Deep Racer', 'Jetson Car', 'R.A.C.E.', 'News', 'Press'];
@Input() id: string; // ID of the blog
@Input() tagsInput: string[];
@ViewChild('tagInput', {static: false}) tagInput: ElementRef<HTMLInputElement>;
@ViewChild('auto', {static: false}) matAutocomplete: MatAutocomplete;
constructor(
private afs: AngularFirestore
) {
this.filteredTags = this.tagCtrl.valueChanges.pipe(
startWith(null),
map((tag: string | null) => tag ? this._filter(tag) : this.alltags.slice()));
}
async ngOnInit() {
// TODO Refactor this, this is messy because it's a double subscription to postDoc for no reason, just can't figure out async
this.postDoc = this.afs.doc('posts/' + this.id);
this.postDoc.valueChanges().subscribe(v => {
this.tags = v.tags;
}); }
/**
* Add a new chiop
* @param event MatChipInputEvent
*/
add(event: MatChipInputEvent): void {
// Add tag only when MatAutocomplete is not open
// To make sure this does not conflict with OptionSelected Event
if (!this.matAutocomplete.isOpen && event.value) {
const input = event.input;
const value = event.value;
// Add our tag
if ((value || '').trim()) {
this.tags.push(value.trim());
}
// Reset the input value
if (input) {
input.value = '';
}
// Reset form ctrl
this.tagCtrl.setValue(null);
}
// Updates post with new tags
this.postDoc.update({
tags: this.tags
});
}
/**
* Removes tags from the list
* @param tag text of tag
*/
remove(tag: string): void {
const index = this.tags.indexOf(tag);
if (index >= 0) {
this.tags.splice(index, 1);
}
this.postDoc.update({
tags: this.tags
});
}
/**
* Handles selection of autocomplete tag
* @param event Event when autocomplete option is selected
*/
selected(event: MatAutocompleteSelectedEvent): void {
// Pushes the selected autocomplete to the tag list
this.tags.push(event.option.viewValue);
// Resets the input
this.tagCtrl.setValue(null);
// Updates the database
this.postDoc.update({
tags: this.tags
});
}
/**
* Method to filter tags and make sure they're usable
*/
private _filter(value: string): string[] {
const filterValue = value.toLowerCase();
return this.alltags.filter(tag => tag.toLowerCase().indexOf(filterValue) === 0);
}
// TODO WET CODE
public getColor(tag: string): string {
switch (tag) {
case 'Machine Learning':
return '#e53935';
break;
case 'AI':
return '#8e24aa';
break;
case 'Deep Racer':
return '#43a047';
break;
case 'Jetson Car':
return '#fb8c00';
break;
case 'News':
return '#00897b';
break;
case 'Press':
return '#1e88e5';
break;
default:
return '#546e7a';
}
}
}