refactor(editor): Rewrite TabBar to composition API (no-changelog) (#9231)

This commit is contained in:
Alex Grozav 2024-04-29 16:10:48 +03:00 committed by GitHub
parent 2917d04766
commit c6b4c6dbf2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 80 additions and 38 deletions

View file

@ -6,8 +6,8 @@
<TabBar
v-if="onWorkflowPage"
:items="tabBarItems"
:active-tab="activeHeaderTab"
@select="onTabSelected"
:model-value="activeHeaderTab"
@update:model-value="onTabSelected"
/>
</div>
</div>

View file

@ -0,0 +1,57 @@
import { fireEvent } from '@testing-library/vue';
import { createComponentRenderer } from '@/__tests__/render';
import TabBar from '@/components/MainHeader/TabBar.vue';
const renderComponent = createComponentRenderer(TabBar);
describe('TabBar', () => {
const items = [
{ name: 'Workflow', value: 'workflow' },
{ name: 'Executions', value: 'executions' },
];
it('should render the correct number of tabs', async () => {
const { findAllByRole } = renderComponent({
props: {
items,
modelValue: 'workflow',
},
});
const tabs = await findAllByRole('radio');
expect(tabs.length).toBe(2);
});
it('should emit update:modelValue event when a tab is clicked', async () => {
const { findAllByRole, emitted } = renderComponent({
props: {
items,
modelValue: 'workflow',
},
});
const tabs = await findAllByRole('radio');
const executionsTab = tabs[1];
await fireEvent.click(executionsTab);
expect(emitted()).toHaveProperty('update:modelValue');
});
it('should update the active tab when modelValue prop changes', async () => {
const { findAllByRole, rerender } = renderComponent({
props: {
items,
modelValue: 'workflow',
},
});
await rerender({ modelValue: 'executions' });
const tabs = await findAllByRole('radio');
const executionsTab = tabs[1];
const executionsTabButton = executionsTab.querySelector('.button');
expect(executionsTabButton).toHaveClass('active');
});
});

View file

@ -4,50 +4,35 @@
:class="{
[$style.container]: true,
['tab-bar-container']: true,
[$style.menuCollapsed]: mainSidebarCollapsed,
}"
>
<n8n-radio-buttons :model-value="activeTab" :options="items" @update:model-value="onSelect" />
<N8nRadioButtons
:model-value="modelValue"
:options="items"
@update:model-value="onUpdateModelValue"
/>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import type { PropType } from 'vue';
import type { ITabBarItem } from '@/Interface';
<script lang="ts" setup>
import { MAIN_HEADER_TABS } from '@/constants';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import type { ITabBarItem } from '@/Interface';
export default defineComponent({
name: 'TabBar',
props: {
items: {
type: Array as PropType<ITabBarItem[]>,
required: true,
},
activeTab: {
type: String,
default: MAIN_HEADER_TABS.WORKFLOW,
},
withDefaults(
defineProps<{
items: ITabBarItem[];
modelValue?: string;
}>(),
{
modelValue: MAIN_HEADER_TABS.WORKFLOW,
},
data() {
return {
MAIN_HEADER_TABS,
};
},
computed: {
...mapStores(useUIStore),
mainSidebarCollapsed(): boolean {
return this.uiStore.sidebarMenuCollapsed;
},
},
methods: {
onSelect(tab: string, event: MouseEvent): void {
this.$emit('select', tab, event);
},
},
});
);
const emit = defineEmits(['update:modelValue']);
function onUpdateModelValue(tab: string, event: MouseEvent): void {
emit('update:modelValue', tab, event);
}
</script>
<style module lang="scss">