mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 11:51:02 +00:00
Fix active tab not updating on prop change (#2712)
This commit is contained in:
parent
fd8f35a879
commit
fe489287fc
6 changed files with 42 additions and 43 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}` });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue