mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-07 14:08:14 +08:00
Merge pull request #5708 from yan9651688/fix/issue-5524-model-plaza-home
fix(frontend): show model plaza entry on /home
This commit is contained in:
@@ -40,6 +40,15 @@
|
||||
>
|
||||
<Icon name="book" size="md" />
|
||||
</a>
|
||||
<router-link
|
||||
v-if="showModelPlazaEntry"
|
||||
to="/model-plaza"
|
||||
class="flex h-10 shrink-0 items-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:text-dark-400 dark:hover:bg-dark-800 dark:hover:text-white"
|
||||
:title="t('nav.modelPlaza')"
|
||||
>
|
||||
<Icon name="grid" size="md" />
|
||||
<span class="hidden sm:inline">{{ t('nav.modelPlaza') }}</span>
|
||||
</router-link>
|
||||
<button
|
||||
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg text-gray-500 hover:bg-gray-100 dark:text-dark-400 dark:hover:bg-dark-800"
|
||||
:title="isDark ? t('home.switchToLight') : t('home.switchToDark')"
|
||||
@@ -132,6 +141,17 @@
|
||||
<Icon name="book" size="md" />
|
||||
</a>
|
||||
|
||||
<!-- Model Plaza Link -->
|
||||
<router-link
|
||||
v-if="showModelPlazaEntry"
|
||||
to="/model-plaza"
|
||||
class="inline-flex items-center gap-1.5 rounded-lg p-2 text-sm text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 dark:text-dark-400 dark:hover:bg-dark-800 dark:hover:text-white"
|
||||
:title="t('nav.modelPlaza')"
|
||||
>
|
||||
<Icon name="grid" size="md" />
|
||||
<span class="hidden sm:inline">{{ t('nav.modelPlaza') }}</span>
|
||||
</router-link>
|
||||
|
||||
<!-- Theme Toggle -->
|
||||
<button
|
||||
@click="toggleTheme"
|
||||
@@ -480,6 +500,7 @@ import { useAuthStore, useAppStore } from '@/stores'
|
||||
import LocaleSwitcher from '@/components/common/LocaleSwitcher.vue'
|
||||
import Icon from '@/components/icons/Icon.vue'
|
||||
import { sanitizeUrl } from '@/utils/url'
|
||||
import { FeatureFlags, isFeatureFlagEnabled } from '@/utils/featureFlags'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -494,6 +515,7 @@ const docUrl = computed(() => sanitizeUrl(appStore.cachedPublicSettings?.doc_url
|
||||
const homeContent = computed(() => appStore.cachedPublicSettings?.home_content || '')
|
||||
const hasHomeContent = computed(() => homeContent.value.trim().length > 0)
|
||||
const compactHomeEnabled = computed(() => appStore.cachedPublicSettings?.compact_home_enabled === true)
|
||||
const modelPlazaEnabled = computed(() => isFeatureFlagEnabled(FeatureFlags.modelPlaza))
|
||||
|
||||
// Check if homeContent is a URL (for iframe display)
|
||||
const isHomeContentUrl = computed(() => {
|
||||
@@ -509,6 +531,12 @@ const githubUrl = 'https://github.com/Wei-Shaw/sub2api'
|
||||
|
||||
// Auth state
|
||||
const isAuthenticated = computed(() => authStore.isAuthenticated)
|
||||
const modelPlazaRequiresAuth = computed(
|
||||
() => appStore.cachedPublicSettings?.model_plaza_require_auth === true,
|
||||
)
|
||||
const showModelPlazaEntry = computed(
|
||||
() => modelPlazaEnabled.value && (isAuthenticated.value || !modelPlazaRequiresAuth.value),
|
||||
)
|
||||
const isAdmin = computed(() => authStore.isAdmin)
|
||||
const dashboardPath = computed(() => isAdmin.value ? '/admin/dashboard' : '/dashboard')
|
||||
const userInitial = computed(() => {
|
||||
|
||||
@@ -25,6 +25,10 @@ vi.mock('@/stores', () => ({
|
||||
useAuthStore: () => authStore,
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/app', () => ({
|
||||
useAppStore: () => appStore,
|
||||
}))
|
||||
|
||||
vi.mock('vue-i18n', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('vue-i18n')>()
|
||||
return {
|
||||
@@ -55,6 +59,13 @@ function compactDestination(wrapper: ReturnType<typeof mountHome>) {
|
||||
return wrapper.get('[data-testid="compact-home"]').findComponent(RouterLinkStub).props('to')
|
||||
}
|
||||
|
||||
function modelPlazaDestination(wrapper: ReturnType<typeof mountHome>) {
|
||||
return wrapper
|
||||
.findAllComponents(RouterLinkStub)
|
||||
.find((link) => link.props('to') === '/model-plaza')
|
||||
?.props('to')
|
||||
}
|
||||
|
||||
describe('HomeView compact mode', () => {
|
||||
beforeEach(() => {
|
||||
authStore.isAuthenticated = false
|
||||
@@ -119,4 +130,55 @@ describe('HomeView compact mode', () => {
|
||||
expect(authStore.checkAuth).toHaveBeenCalledOnce()
|
||||
expect(appStore.fetchPublicSettings).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('shows the model plaza link to anonymous visitors when public access is enabled', () => {
|
||||
const wrapper = mountHome({
|
||||
compact_home_enabled: true,
|
||||
model_plaza_enabled: true,
|
||||
model_plaza_require_auth: false,
|
||||
})
|
||||
|
||||
expect(modelPlazaDestination(wrapper)).toBe('/model-plaza')
|
||||
})
|
||||
|
||||
it('hides the model plaza link from anonymous visitors when sign-in is required', () => {
|
||||
const wrapper = mountHome({
|
||||
compact_home_enabled: true,
|
||||
model_plaza_enabled: true,
|
||||
model_plaza_require_auth: true,
|
||||
})
|
||||
|
||||
expect(modelPlazaDestination(wrapper)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('shows the model plaza link to authenticated visitors when sign-in is required', () => {
|
||||
authStore.isAuthenticated = true
|
||||
|
||||
const wrapper = mountHome({
|
||||
compact_home_enabled: true,
|
||||
model_plaza_enabled: true,
|
||||
model_plaza_require_auth: true,
|
||||
})
|
||||
|
||||
expect(modelPlazaDestination(wrapper)).toBe('/model-plaza')
|
||||
})
|
||||
|
||||
it('shows the model plaza link in the default home header', () => {
|
||||
const wrapper = mountHome({
|
||||
model_plaza_enabled: true,
|
||||
model_plaza_require_auth: false,
|
||||
})
|
||||
|
||||
expect(modelPlazaDestination(wrapper)).toBe('/model-plaza')
|
||||
})
|
||||
|
||||
it('hides the model plaza link when the feature is disabled', () => {
|
||||
const wrapper = mountHome({
|
||||
compact_home_enabled: true,
|
||||
model_plaza_enabled: false,
|
||||
model_plaza_require_auth: false,
|
||||
})
|
||||
|
||||
expect(modelPlazaDestination(wrapper)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user