mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-10-31 08:41:51 +00:00 
			
		
		
		
	Header and Tabs UI Improvements (#1290)
Some improvements to the Page Header and Tab UI. Original | New :--------:|:-------:  |   |   |   |   |  What? - Create a new Scaffold component, which includes the header and tabs required for a page. - Use this component to wrap all the views that have a header. - Ensures consistency in headers between different pages. - [x] Add support to use custom html/component in place of title (for repo page, pipeline page, etc) - [x] Add support of right icon buttons (for repo page, pipeline page, etc) - [x] Refactor tabs handling using compositions (useTabsProvider, useTabsClient) - [x] Make new header ui resposive
This commit is contained in:
		
							
								
								
									
										64
									
								
								web/src/components/layout/scaffold/Header.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								web/src/components/layout/scaffold/Header.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| <template> | ||||
|   <div class="bg-white dark:bg-dark-gray-900 border-b dark:border-gray-700"> | ||||
|     <FluidContainer class="!py-0"> | ||||
|       <div class="flex flex-wrap items-center justify-between py-4 <md:flex-row <md:gap-y-4"> | ||||
|         <div | ||||
|           class="flex flex-wrap items-center justify-start <md:w-full <md:justify-center" | ||||
|           :class="{ | ||||
|             'md:flex-1': searchBoxPresent, | ||||
|           }" | ||||
|         > | ||||
|           <IconButton v-if="goBack" icon="back" :title="$t('back')" class="mr-2 <md:hidden" @click="goBack" /> | ||||
|           <h1 class="flex flex-wrap text-xl text-color items-center gap-x-2"> | ||||
|             <slot name="title" /> | ||||
|           </h1> | ||||
|         </div> | ||||
|         <TextField | ||||
|           v-if="searchBoxPresent" | ||||
|           class="w-auto !bg-gray-100 !dark:bg-dark-gray-600 <md:w-full <md:order-3" | ||||
|           input-class="!placeholder-gray-500" | ||||
|           :placeholder="$t('search')" | ||||
|           :model-value="search" | ||||
|           @update:model-value="(value: string) => $emit('update:search', value)" | ||||
|         /> | ||||
|         <div | ||||
|           v-if="$slots.titleActions" | ||||
|           class="flex flex-wrap items-center justify-end gap-x-2 <md:w-full <md:justify-center" | ||||
|           :class="{ | ||||
|             'md:flex-1': searchBoxPresent, | ||||
|           }" | ||||
|         > | ||||
|           <slot name="titleActions" /> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <div v-if="enableTabs" class="flex flex-wrap justify-between"> | ||||
|         <Tabs class="<md:order-2" /> | ||||
|         <div | ||||
|           v-if="$slots.titleActions" | ||||
|           class="flex items-center justify-end gap-x-2 md:mb-2 <md:w-full <md:justify-center <md:order-1" | ||||
|         > | ||||
|           <slot name="tabActions" /> | ||||
|         </div> | ||||
|       </div> | ||||
|     </FluidContainer> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import TextField from '~/components/form/TextField.vue'; | ||||
| import FluidContainer from '~/components/layout/FluidContainer.vue'; | ||||
|  | ||||
| import Tabs from './Tabs.vue'; | ||||
|  | ||||
| export interface Props { | ||||
|   goBack?: () => void; | ||||
|   enableTabs?: boolean; | ||||
|   search?: string; | ||||
| } | ||||
|  | ||||
| const props = defineProps<Props>(); | ||||
| defineEmits(['update:search']); | ||||
|  | ||||
| const searchBoxPresent = props.search !== undefined; | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user