Skip to content

Commit 16389fa

Browse files
sreenathsJohanAhlen
authored andcommitted
[ui] Vue 3 - Migrated Tabs component
1 parent d458a8b commit 16389fa

File tree

6 files changed

+121
-75
lines changed

6 files changed

+121
-75
lines changed

desktop/core/src/desktop/js/components/Tab.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ describe('Tab.vue', () => {
2222
let reportedTab: Tab | undefined;
2323
const wrapper = shallowMount(Tab, {
2424
propsData: { title: 'Tab title' },
25-
provide: {
26-
addTab: (tab: Tab): void => {
27-
reportedTab = tab;
28-
},
29-
removeTab: () => {
30-
// Empty
25+
global: {
26+
provide: {
27+
addTab: (tab: Tab): void => {
28+
reportedTab = tab;
29+
},
30+
removeTab: () => {
31+
// Empty
32+
}
3133
}
3234
},
3335
slots: {

desktop/core/src/desktop/js/components/Tab.vue

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@
1717
-->
1818

1919
<template>
20-
<div v-if="!lazy || rendered" v-show="isActive">
20+
<div v-if="!lazy || rendered" v-show="def.isActive">
2121
<slot />
2222
</div>
2323
</template>
2424

2525
<script lang="ts">
26-
import { defineComponent, inject, Component } from 'vue';
26+
import { defineComponent, inject } from 'vue';
2727
28-
const Tab:Component = defineComponent({
29-
name: 'Tab',
28+
export interface TabRef {
29+
title: string;
30+
isActive: boolean;
31+
}
32+
33+
export default defineComponent({
3034
props: {
3135
title: {
3236
type: String,
@@ -38,44 +42,59 @@
3842
}
3943
},
4044
41-
setup(): {
42-
addTab?: (tab: typeof Tab) => void,
43-
removeTab?: (tab: typeof Tab) => void,
45+
setup(
46+
props
47+
): {
48+
addTab?: (tab: TabRef) => void;
49+
removeTab?: (tab: TabRef) => void;
4450
45-
isActive: boolean,
46-
rendered: boolean
51+
def: TabRef;
4752
} {
4853
return {
4954
addTab: inject('addTab'),
5055
removeTab: inject('removeTab'),
5156
52-
isActive: false,
57+
def: {
58+
title: props.title,
59+
isActive: false
60+
}
61+
};
62+
},
63+
64+
data(): {
65+
rendered: boolean;
66+
} {
67+
return {
5368
rendered: false
5469
};
5570
},
5671
57-
watch: {
58-
isActive(): void {
59-
if (this.isActive) {
60-
this.rendered = true;
72+
created() {
73+
this.$watch(
74+
(): boolean => this.def.isActive,
75+
(isActive: boolean): void => {
76+
if (isActive) {
77+
this.rendered = true;
78+
}
6179
}
62-
}
80+
);
6381
},
6482
6583
mounted(): void {
6684
if (this.addTab) {
67-
this.addTab(this);
68-
}
69-
},
70-
71-
destroyed(): void {
72-
if (this.removeTab) {
73-
this.removeTab(this);
85+
this.addTab(this.def);
7486
}
7587
}
76-
})
7788
78-
export default Tab;
89+
// TODO
90+
// destroyed(): was deprecated, need to rearchitect the component.
91+
// Whenever parent is rendered mount, unmount is called causing an to prevent infinit loop.
92+
// unmounted(): void {
93+
// if (this.removeTab) {
94+
// this.removeTab(this.def);
95+
// }
96+
// }
97+
});
7998
</script>
8099

81100
<style lang="scss" scoped></style>

desktop/core/src/desktop/js/components/Tabs.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// See the License for the specific language governing permissions and
1515
// limitations under the License.
1616

17-
import Vue from 'vue';
17+
import { nextTick } from 'vue';
1818
import { mount, shallowMount } from '@vue/test-utils';
1919
import Tabs from './Tabs.vue';
2020
import Tab from './Tab.vue';
@@ -30,11 +30,14 @@ describe('Tabs.vue', () => {
3030
slots: {
3131
default: '<tab title="foo">foo</tab><tab title="bar">bar</tab>'
3232
},
33-
stubs: {
34-
tab: Tab
33+
global: {
34+
stubs: {
35+
tab: Tab
36+
}
3537
}
3638
});
37-
await Vue.nextTick();
39+
40+
await nextTick();
3841
expect(wrapper.element).toMatchSnapshot();
3942
});
4043
});

desktop/core/src/desktop/js/components/Tabs.vue

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,52 @@
3535
</template>
3636

3737
<script lang="ts">
38-
import Vue from 'vue';
39-
import Component from 'vue-class-component';
40-
import { Provide } from 'vue-property-decorator';
41-
import Tab from './Tab.vue';
38+
import { defineComponent } from 'vue';
4239
43-
@Component
44-
export default class Tabs extends Vue {
45-
tabs: Tab[] = [];
40+
import { TabRef } from './Tab.vue';
4641
47-
@Provide()
48-
addTab(tab: Tab): void {
49-
this.tabs.push(tab);
50-
if (this.tabs.length === 1) {
51-
this.selectTab(this.tabs[0]);
52-
}
53-
}
54-
55-
@Provide()
56-
removeTab(tab: Tab): void {
57-
const index = this.tabs.indexOf(tab);
58-
if (index !== -1) {
59-
this.$delete(this.tabs, index);
60-
if (tab.isActive && this.tabs.length) {
61-
this.tabs[Math.max(0, index - 1)].isActive = true;
42+
export default defineComponent({
43+
provide(): {
44+
addTab: (tab: TabRef) => void;
45+
removeTab: (tab: TabRef) => void;
46+
} {
47+
return {
48+
addTab: (tab: TabRef): void => {
49+
if (!this.tabs.find(t => t.title === tab.title)) {
50+
this.tabs.push(tab);
51+
if (this.tabs.length === 1) {
52+
this.selectTab(this.tabs[0]);
53+
}
54+
}
55+
},
56+
removeTab: (tab: TabRef): void => {
57+
const index = this.tabs.indexOf(tab);
58+
if (index !== -1) {
59+
this.tabs.splice(index, 1);
60+
if (tab.isActive && this.tabs.length) {
61+
this.tabs[Math.max(0, index - 1)].isActive = true;
62+
}
63+
}
6264
}
63-
}
64-
}
65+
};
66+
},
67+
68+
data(): {
69+
tabs: TabRef[];
70+
} {
71+
return {
72+
tabs: []
73+
};
74+
},
6575
66-
selectTab(tab: Tab): void {
67-
this.tabs.forEach(other => {
68-
other.isActive = other === tab;
69-
});
76+
methods: {
77+
selectTab(tab: TabRef): void {
78+
this.tabs.forEach(other => {
79+
other.isActive = other === tab;
80+
});
81+
}
7082
}
71-
}
83+
});
7284
</script>
7385

7486
<style lang="scss" scoped>

desktop/core/src/desktop/js/components/__snapshots__/Tab.test.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ exports[`Tab.vue should render 1`] = `
44
<div
55
style="display: none;"
66
>
7-
<div>
8-
Some tab content
9-
</div>
7+
8+
<stub />
9+
1010
</div>
1111
`;

desktop/core/src/desktop/js/components/__snapshots__/Tabs.test.ts.snap

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ exports[`Tabs.vue should render empty tabs 1`] = `
44
<div
55
class="hue-tabs"
66
>
7-
<ul />
8-
7+
<ul>
8+
9+
10+
</ul>
911
<div
1012
class="hue-tab-container"
11-
/>
13+
>
14+
15+
16+
</div>
1217
</div>
1318
`;
1419

@@ -17,35 +22,40 @@ exports[`Tabs.vue should render tabs 1`] = `
1722
class="hue-tabs"
1823
>
1924
<ul>
25+
2026
<li
2127
class="active"
2228
>
23-
2429
foo
25-
2630
</li>
2731
<li
2832
class=""
2933
>
30-
3134
bar
32-
3335
</li>
36+
3437
</ul>
35-
3638
<div
3739
class="hue-tab-container"
3840
>
41+
42+
3943
<div
40-
style=""
44+
style="display: none;"
4145
>
46+
4247
foo
48+
4349
</div>
4450
<div
4551
style="display: none;"
4652
>
53+
4754
bar
55+
4856
</div>
57+
58+
4959
</div>
5060
</div>
5161
`;

0 commit comments

Comments
 (0)