Fix active tab not updating on prop change (#2712)

This commit is contained in:
Anbraten 2023-11-03 16:01:14 +01:00 committed by GitHub
parent fd8f35a879
commit fe489287fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 43 deletions

View file

@ -62,7 +62,10 @@ const props = defineProps<{
search?: string;
fullWidth?: boolean;
}>();
defineEmits(['update:search']);
defineEmits<{
(event: 'update:search', query: string): void;
}>();
const searchBoxPresent = props.search !== undefined;
</script>

View file

@ -18,7 +18,7 @@
</template>
<script setup lang="ts">
import { toRef } from 'vue';
import { computed, ref, watch } from 'vue';
import Container from '~/components/layout/Container.vue';
import { useTabsProvider } from '~/compositions/useTabs';
@ -33,7 +33,7 @@ const props = defineProps<{
// Tabs
enableTabs?: boolean;
disableHashMode?: boolean;
disableTabUrlHashMode?: boolean;
activeTab?: string;
// Content
@ -41,15 +41,29 @@ const props = defineProps<{
}>();
const emit = defineEmits<{
(event: 'update:activeTab', value: string): void;
(event: 'update:activeTab', value: string | undefined): void;
(event: 'update:search', value: string): void;
}>();
if (props.enableTabs) {
const internalActiveTab = ref(props.activeTab);
watch(
() => props.activeTab,
(activeTab) => {
internalActiveTab.value = activeTab;
},
);
useTabsProvider({
activeTabProp: toRef(props, 'activeTab'),
disableHashMode: toRef(props, 'disableHashMode'),
updateActiveTabProp: (value) => emit('update:activeTab', value),
activeTab: computed({
get: () => internalActiveTab.value,
set: (value) => {
internalActiveTab.value = value;
emit('update:activeTab', value);
},
}),
disableUrlHashMode: computed(() => props.disableTabUrlHashMode || false),
});
}
</script>

View file

@ -26,7 +26,7 @@ import { Tab, useTabsClient } from '~/compositions/useTabs';
const router = useRouter();
const route = useRoute();
const { activeTab, tabs, disableHashMode } = useTabsClient();
const { activeTab, tabs, disableUrlHashMode } = useTabsClient();
async function selectTab(tab: Tab) {
if (tab.id === undefined) {
@ -34,7 +34,8 @@ async function selectTab(tab: Tab) {
}
activeTab.value = tab.id;
if (!disableHashMode.value) {
if (!disableUrlHashMode.value) {
await router.replace({ params: route.params, hash: `#${tab.id}` });
}
}

View file

@ -1,4 +1,4 @@
import { computed, inject, onMounted, provide, Ref, ref } from 'vue';
import { inject, onMounted, provide, Ref, ref } from 'vue';
import { useRoute } from 'vue-router';
export type Tab = {
@ -7,58 +7,39 @@ export type Tab = {
};
export function useTabsProvider({
activeTabProp,
disableHashMode,
updateActiveTabProp,
activeTab,
disableUrlHashMode,
}: {
activeTabProp: Ref<string | undefined>;
updateActiveTabProp: (tab: string) => void;
disableHashMode: Ref<boolean>;
activeTab: Ref<string | undefined>;
disableUrlHashMode: Ref<boolean>;
}) {
const route = useRoute();
const tabs = ref<Tab[]>([]);
const activeTab = ref<string>('');
provide('tabs', tabs);
provide(
'disable-hash-mode',
computed(() => disableHashMode.value),
);
provide(
'active-tab',
computed({
get: () => activeTab.value,
set: (value) => {
activeTab.value = value;
updateActiveTabProp(value);
},
}),
);
provide('disable-url-hash-mode', disableUrlHashMode);
provide('active-tab', activeTab);
onMounted(() => {
if (activeTabProp.value) {
activeTab.value = activeTabProp.value;
if (activeTab.value !== undefined) {
return;
}
const hashTab = route.hash.replace(/^#/, '');
if (hashTab) {
activeTab.value = hashTab;
return;
}
activeTab.value = tabs.value[0].id;
// eslint-disable-next-line no-param-reassign
activeTab.value = hashTab ?? tabs.value[0].id;
});
}
export function useTabsClient() {
const tabs = inject<Ref<Tab[]>>('tabs');
const disableHashMode = inject<Ref<boolean>>('disable-hash-mode');
const disableUrlHashMode = inject<Ref<boolean>>('disable-url-hash-mode');
const activeTab = inject<Ref<string>>('active-tab');
if (activeTab === undefined || tabs === undefined || disableHashMode === undefined) {
if (activeTab === undefined || tabs === undefined || disableUrlHashMode === undefined) {
throw new Error('Please use this "useTabsClient" composition inside a component running "useTabsProvider".');
}
return { activeTab, tabs, disableHashMode };
return { activeTab, tabs, disableUrlHashMode };
}

View file

@ -3,7 +3,7 @@
v-if="repo && repoPermissions && $route.meta.repoHeader"
v-model:activeTab="activeTab"
enable-tabs
disable-hash-mode
disable-tab-url-hash-mode
>
<template #title>
<span class="flex">

View file

@ -3,7 +3,7 @@
v-if="pipeline && repo"
v-model:activeTab="activeTab"
enable-tabs
disable-hash-mode
disable-tab-url-hash-mode
:go-back="goBack"
:fluid-content="activeTab === 'tasks'"
full-width-header