From a027a4754493fdc80b087dfce0449d849ed6c3b1 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 5 Oct 2022 15:16:06 +0200 Subject: [PATCH] feat: tag has a default and cannot be deselected, timeline allows picking a skill and vice-versa --- src/App.vue | 23 +++++++++++-- src/components/SkillPicker.vue | 59 +++++++++++++++++++++------------- src/components/Timeline.vue | 4 ++- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/App.vue b/src/App.vue index 8364b5c..0450300 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,8 +1,8 @@ @@ -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); + } + } diff --git a/src/components/SkillPicker.vue b/src/components/SkillPicker.vue index 6036279..493326f 100644 --- a/src/components/SkillPicker.vue +++ b/src/components/SkillPicker.vue @@ -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); } } diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue index 77acb2b..313bd60 100644 --- a/src/components/Timeline.vue +++ b/src/components/Timeline.vue @@ -17,7 +17,7 @@
- +
@@ -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;