feat: tag has a default and cannot be deselected, timeline allows picking a skill and vice-versa

This commit is contained in:
Adrien Marquès 2022-10-05 15:16:06 +02:00
parent 9b02041ca8
commit a027a47544
Signed by: xdrm-brackets
GPG Key ID: D75243CA236D825E
3 changed files with 61 additions and 25 deletions

View File

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

View File

@ -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!);
}
// 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){
if( picked ){ // select
this.sel = id;
this.loadDetails(id);
this.$emit('pick', id);
return;
}
// deselect
this.sel = null;
this.details = null;
this.$emit('pick', null);
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);
}
}

View File

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