Skip to content

Commit c4477fc

Browse files
[feat] Add feature-flagged upload button to asset browser (#6665)
## Summary Adds an upload button to the asset browser modal, controlled by the `model_upload_button_enabled` backend feature flag. ## Changes - **What**: Added upload button with PrimeVue primary styling to asset browser header - **Feature Flag**: Button only appears when backend returns `model_upload_button_enabled: true` - **Localization**: Added `assetBrowser.uploadModel` translation key - **Click Handler**: Currently logs to console (implementation pending) ## Review Focus - Feature flag integration using `useFeatureFlags` composable - Button styling matches PrimeVue primary color scheme - Proper placement in header with flexbox layout ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6665-feat-Add-feature-flagged-upload-button-to-asset-browser-2a96d73d365081c7a05bdc33bed7f7fd) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude <[email protected]>
1 parent ef46f0c commit c4477fc

File tree

4 files changed

+48
-12
lines changed

4 files changed

+48
-12
lines changed

src/composables/useFeatureFlags.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { api } from '@/scripts/api'
88
export enum ServerFeatureFlag {
99
SUPPORTS_PREVIEW_METADATA = 'supports_preview_metadata',
1010
MAX_UPLOAD_SIZE = 'max_upload_size',
11-
MANAGER_SUPPORTS_V4 = 'extension.manager.supports_v4'
11+
MANAGER_SUPPORTS_V4 = 'extension.manager.supports_v4',
12+
MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled'
1213
}
1314

1415
/**
@@ -24,6 +25,12 @@ export function useFeatureFlags() {
2425
},
2526
get supportsManagerV4() {
2627
return api.getServerFeature(ServerFeatureFlag.MANAGER_SUPPORTS_V4)
28+
},
29+
get modelUploadButtonEnabled() {
30+
return api.getServerFeature(
31+
ServerFeatureFlag.MODEL_UPLOAD_BUTTON_ENABLED,
32+
false
33+
)
2734
}
2835
})
2936

src/locales/en/main.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,7 @@
19841984
"failedToCreateNode": "Failed to create node. Please try again or check console for details.",
19851985
"noModelsInFolder": "No {type} available in this folder",
19861986
"searchAssetsPlaceholder": "Type to search...",
1987+
"uploadModel": "Upload model",
19871988
"allModels": "All Models",
19881989
"allCategory": "All {category}",
19891990
"unknown": "Unknown",

src/platform/assets/components/AssetBrowserModal.vue

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,27 @@
2121
</template>
2222

2323
<template #header>
24-
<SearchBox
25-
v-model="searchQuery"
26-
:autofocus="true"
27-
size="lg"
28-
:placeholder="$t('assetBrowser.searchAssetsPlaceholder')"
29-
class="max-w-96"
30-
/>
24+
<div class="flex w-full items-center justify-between gap-2">
25+
<SearchBox
26+
v-model="searchQuery"
27+
:autofocus="true"
28+
size="lg"
29+
:placeholder="$t('assetBrowser.searchAssetsPlaceholder')"
30+
class="max-w-96"
31+
/>
32+
<IconTextButton
33+
v-if="isUploadButtonEnabled"
34+
type="accent"
35+
size="md"
36+
class="!h-10 [&>span]:hidden md:[&>span]:inline"
37+
:label="$t('assetBrowser.uploadModel')"
38+
:on-click="handleUploadClick"
39+
>
40+
<template #icon>
41+
<i class="icon-[lucide--upload]" />
42+
</template>
43+
</IconTextButton>
44+
</div>
3145
</template>
3246

3347
<template #contentFilter>
@@ -52,9 +66,11 @@ import { useAsyncState } from '@vueuse/core'
5266
import { computed, provide, watch } from 'vue'
5367
import { useI18n } from 'vue-i18n'
5468
69+
import IconTextButton from '@/components/button/IconTextButton.vue'
5570
import SearchBox from '@/components/input/SearchBox.vue'
5671
import BaseModalLayout from '@/components/widget/layout/BaseModalLayout.vue'
5772
import LeftSidePanel from '@/components/widget/panel/LeftSidePanel.vue'
73+
import { useFeatureFlags } from '@/composables/useFeatureFlags'
5874
import AssetFilterBar from '@/platform/assets/components/AssetFilterBar.vue'
5975
import AssetGrid from '@/platform/assets/components/AssetGrid.vue'
6076
import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser'
@@ -168,4 +184,11 @@ function handleAssetSelectAndEmit(asset: AssetDisplayItem) {
168184
// It handles the appropriate transformation (filename extraction or full asset)
169185
props.onSelect?.(asset)
170186
}
187+
188+
const { flags } = useFeatureFlags()
189+
const isUploadButtonEnabled = computed(() => flags.modelUploadButtonEnabled)
190+
191+
function handleUploadClick() {
192+
// Will be implemented in the future commit
193+
}
171194
</script>

src/types/buttonTypes.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { HTMLAttributes } from 'vue'
22

33
export type ButtonSize = 'fit-content' | 'sm' | 'md'
4-
type ButtonType = 'primary' | 'secondary' | 'transparent'
4+
type ButtonType = 'primary' | 'secondary' | 'transparent' | 'accent'
55
type ButtonBorder = boolean
66

77
export interface BaseButtonProps {
@@ -28,7 +28,9 @@ export const getButtonTypeClasses = (type: ButtonType = 'primary') => {
2828
secondary:
2929
'bg-white border-none text-neutral-950 dark-theme:bg-zinc-700 dark-theme:text-white',
3030
transparent:
31-
'bg-transparent border-none text-neutral-600 dark-theme:text-neutral-200'
31+
'bg-transparent border-none text-neutral-600 dark-theme:text-neutral-200',
32+
accent:
33+
'bg-primary-background hover:bg-primary-background-hover border-none text-white font-bold'
3234
} as const
3335

3436
return baseByType[type]
@@ -40,14 +42,17 @@ export const getBorderButtonTypeClasses = (type: ButtonType = 'primary') => {
4042
'bg-neutral-900 text-white dark-theme:bg-white dark-theme:text-neutral-900',
4143
secondary:
4244
'bg-white text-neutral-950 dark-theme:bg-zinc-700 dark-theme:text-white',
43-
transparent: 'bg-transparent text-neutral-600 dark-theme:text-neutral-400'
45+
transparent: 'bg-transparent text-neutral-600 dark-theme:text-neutral-400',
46+
accent:
47+
'bg-primary-background hover:bg-primary-background-hover text-white font-bold'
4448
} as const
4549

4650
const borderByType = {
4751
primary: 'border border-solid border-white dark-theme:border-neutral-900',
4852
secondary: 'border border-solid border-neutral-950 dark-theme:border-white',
4953
transparent:
50-
'border border-solid border-neutral-950 dark-theme:border-white'
54+
'border border-solid border-neutral-950 dark-theme:border-white',
55+
accent: 'border border-solid border-primary-background'
5156
} as const
5257

5358
return `${baseByType[type]} ${borderByType[type]}`

0 commit comments

Comments
 (0)