feat: tag has a default and cannot be deselected, timeline allows picking a skill and vice-versa
This commit is contained in:
parent
9b02041ca8
commit
a027a47544
23
src/App.vue
23
src/App.vue
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<Home/>
|
||||
<SkillPicker @pick='onPick($event)'/>
|
||||
<Timeline ref='timeline'/>
|
||||
<SkillPicker ref='picker' @pick='onPick($event)'/>
|
||||
<Timeline ref='timeline' @pick='onPicked($event)'/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -24,6 +24,15 @@ import SkillPicker from './components/SkillPicker.vue';
|
|||
export default class App extends Vue {
|
||||
private selected: tID|null = null;
|
||||
|
||||
private mounted() {
|
||||
const picker = this.$refs.picker as SkillPicker;
|
||||
if( picker == null ){
|
||||
return;
|
||||
}
|
||||
picker.select(tID.Vue, false);
|
||||
}
|
||||
|
||||
// skill picker selection -> filters the timeline
|
||||
protected onPick(id: tID|null) {
|
||||
const timeline = this.$refs.timeline as Timeline;
|
||||
if( timeline == null ){
|
||||
|
@ -31,6 +40,16 @@ export default class App extends Vue {
|
|||
}
|
||||
timeline.filter(id);
|
||||
}
|
||||
|
||||
// skill picked from the timeline -> select on the skill picker
|
||||
protected onPicked(id: tID) {
|
||||
const picker = this.$refs.picker as SkillPicker;
|
||||
if( picker == null ){
|
||||
return;
|
||||
}
|
||||
picker.select(id, false);
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
text: string;
|
||||
}
|
||||
|
||||
const DEFAULT_TAG = "all";
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
SkillCard,
|
||||
|
@ -74,29 +76,42 @@
|
|||
private filtered: tID[] = [];
|
||||
|
||||
// available categories (tags)
|
||||
private tags: string[] = skills.tags();
|
||||
private tags: string[] = [DEFAULT_TAG, ...skills.tags()];
|
||||
// currently selected tag
|
||||
private tag: string|null = "web";
|
||||
private tag: string = "web";
|
||||
|
||||
// details section when a skill is selected
|
||||
private details: Details|null = null;
|
||||
|
||||
private mounted() {
|
||||
this.filterByTag();
|
||||
this.loadDetails(this.sel!);
|
||||
}
|
||||
|
||||
protected onPick(id: tID, picked: boolean){
|
||||
if( picked ){ // select
|
||||
this.sel = id;
|
||||
this.loadDetails(id);
|
||||
this.$emit('pick', id);
|
||||
return;
|
||||
}
|
||||
// deselect
|
||||
// selects or deselects a skill. If the skill is not in the current
|
||||
// folder, it navigates to the DEFAULT_TAG folder beforehand. Scrolls to
|
||||
// the selected skill when selected.
|
||||
public select(id: tID, deselect: boolean) {
|
||||
const skill = skills.get(id);
|
||||
if( deselect || skill == null ){
|
||||
this.sel = null;
|
||||
this.details = null;
|
||||
this.$emit('pick', null);
|
||||
return;
|
||||
}
|
||||
|
||||
// not available in current tag filter (folder)
|
||||
// -> navigate to default tag
|
||||
if( skill.tags.indexOf(this.tag) < 0 ){
|
||||
this.onTag(DEFAULT_TAG, true);
|
||||
}
|
||||
|
||||
this.sel = id;
|
||||
this.loadDetails(id);
|
||||
this.$emit('pick', id);
|
||||
}
|
||||
|
||||
protected onPick(id: tID, picked: boolean){
|
||||
this.select(id, !picked);
|
||||
}
|
||||
|
||||
protected onTag(t: string, picked: boolean){
|
||||
|
@ -105,8 +120,8 @@
|
|||
this.filterByTag();
|
||||
return;
|
||||
}
|
||||
if( !picked && t == this.tag ){ // deselect
|
||||
this.tag = null;
|
||||
if( !picked && t == this.tag ){ // back to default
|
||||
this.tag = DEFAULT_TAG;
|
||||
this.filterByTag();
|
||||
return;
|
||||
}
|
||||
|
@ -114,17 +129,17 @@
|
|||
|
||||
// apply filter by tag
|
||||
private filterByTag(){
|
||||
const tag = this.tag;
|
||||
if( tag == null ){
|
||||
this.tag = null;
|
||||
this.filtered = [];
|
||||
if( this.tag == DEFAULT_TAG ){
|
||||
this.filtered = this.ids;
|
||||
} else {
|
||||
this.filtered = skills.filtered(tag);
|
||||
this.filtered = skills.filtered(this.tag);
|
||||
}
|
||||
|
||||
// deselect if selection has been filtered out
|
||||
// maintain selection behavior:
|
||||
// - deselect if current is no more present
|
||||
// - keep if still listed
|
||||
if( this.sel != null && this.filtered.indexOf(this.sel) < 0 ){
|
||||
this.sel = null;
|
||||
this.select(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<img :key="'skill-icon-'+proj.name" class='skill-icon' src='../assets/timeline/skills.svg' />
|
||||
<div :key="'skillset-'+proj.name" class='skillset'>
|
||||
<SkillCard v-for='(id) of proj.skills' :key='id' :id='id'/>
|
||||
<SkillCard v-for='(id) of proj.skills' :key='"timeline-" + proj.name + "-" + id' :id='id' :active='id == skill' @pick='$emit("pick", id)'/>
|
||||
</div>
|
||||
|
||||
<img :key="'desc-icon-'+proj.name" class='desc-icon' src='../assets/timeline/info.svg' />
|
||||
|
@ -119,6 +119,7 @@
|
|||
}
|
||||
})
|
||||
export default class Timeline extends Vue {
|
||||
private skill: tID|null = null;
|
||||
private projects: Project[] = [];
|
||||
|
||||
private mounted() {
|
||||
|
@ -147,6 +148,7 @@
|
|||
}
|
||||
|
||||
public filter(skill: tID|null) {
|
||||
this.skill = skill;
|
||||
if( skill == null ){
|
||||
this.projects = [];
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue