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;