Skip to content

Commit ac7e638

Browse files
userquindanielroe
andauthored
fix(ui): app footer layout and build environment on narrow screens (#1032)
Co-authored-by: Daniel Roe <daniel@roe.dev>
1 parent 77fd97e commit ac7e638

File tree

6 files changed

+134
-20
lines changed

6 files changed

+134
-20
lines changed

app/components/AppFooter.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const showModal = () => modalRef.value?.showModal?.()
1414
>
1515
<div>
1616
<p class="font-mono text-balance m-0 hidden sm:block">{{ $t('tagline') }}</p>
17-
<BuildEnvironment v-if="!isHome" footer />
1817
</div>
1918
<!-- Desktop: Show all links. Mobile: Links are in MobileMenu -->
2019
<div class="hidden sm:flex items-center gap-6 min-h-11 text-xs">
@@ -105,6 +104,7 @@ const showModal = () => modalRef.value?.showModal?.()
105104
</Modal>
106105
</div>
107106
</div>
107+
<BuildEnvironment v-if="!isHome" footer />
108108
<p class="text-xs text-fg-muted text-center sm:text-start m-0">
109109
<span class="sm:hidden">{{ $t('non_affiliation_disclaimer') }}</span>
110110
<span class="hidden sm:inline">{{ $t('trademark_disclaimer') }}</span>

app/components/BuildEnvironment.vue

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
<script setup lang="ts">
2-
defineProps<{
2+
import type { BuildInfo } from '#shared/types'
3+
4+
const { footer = false, buildInfo: buildInfoProp } = defineProps<{
35
footer?: boolean
6+
buildInfo?: BuildInfo
47
}>()
58
69
const { locale } = useI18n()
7-
const buildInfo = useAppConfig().buildInfo
10+
const appConfig = useAppConfig()
11+
const buildInfo = computed(() => buildInfoProp || appConfig.buildInfo)
812
</script>
913

1014
<template>
1115
<div
1216
class="font-mono text-xs text-fg-muted flex items-center gap-2 motion-safe:animate-fade-in motion-safe:animate-fill-both"
13-
:class="footer ? 'mt-4 justify-start' : 'mb-8 justify-center'"
17+
:class="footer ? 'my-1 justify-center sm:justify-start' : 'mb-8 justify-center'"
1418
style="animation-delay: 0.05s"
1519
>
1620
<i18n-t keypath="built_at" scope="global">

modules/build-env.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { BuildInfo } from '../shared/types'
1+
import type { BuildInfo, EnvType } from '../shared/types'
22
import { createResolver, defineNuxtModule } from 'nuxt/kit'
33
import { isCI } from 'std-env'
44
import { getEnv, getFileLastUpdated, version } from '../config/env'
@@ -10,22 +10,37 @@ export default defineNuxtModule({
1010
name: 'npmx:build-env',
1111
},
1212
async setup(_options, nuxt) {
13-
const [{ env, commit, shortCommit, branch }, privacyPolicyDate] = await Promise.all([
14-
getEnv(nuxt.options.dev),
15-
getFileLastUpdated('app/pages/privacy.vue'),
16-
])
17-
13+
let env: EnvType = 'dev'
1814
nuxt.options.appConfig = nuxt.options.appConfig || {}
1915
nuxt.options.appConfig.env = env
20-
nuxt.options.appConfig.buildInfo = {
21-
version,
22-
time: +Date.now(),
23-
commit,
24-
shortCommit,
25-
branch,
26-
env,
27-
privacyPolicyDate,
28-
} satisfies BuildInfo
16+
if (process.env.TEST) {
17+
const time = new Date()
18+
nuxt.options.appConfig.buildInfo = {
19+
env,
20+
version: '0.0.0',
21+
commit: '704987bba88909f3782d792c224bde989569acb9',
22+
shortCommit: '704987b',
23+
branch: 'xxx',
24+
time: time.getTime(),
25+
privacyPolicyDate: time.toISOString(),
26+
} satisfies BuildInfo
27+
} else {
28+
const [{ env: useEnv, commit, shortCommit, branch }, privacyPolicyDate] = await Promise.all([
29+
getEnv(nuxt.options.dev),
30+
getFileLastUpdated('app/pages/privacy.vue'),
31+
])
32+
env = useEnv
33+
nuxt.options.appConfig.env = useEnv
34+
nuxt.options.appConfig.buildInfo = {
35+
version,
36+
time: +Date.now(),
37+
commit,
38+
shortCommit,
39+
branch,
40+
env,
41+
privacyPolicyDate,
42+
} satisfies BuildInfo
43+
}
2944

3045
nuxt.options.nitro.publicAssets = nuxt.options.nitro.publicAssets || []
3146
if (env === 'dev') nuxt.options.nitro.publicAssets.unshift({ dir: resolve('../public-dev') })

shared/types/env.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
export type EnvType = 'dev' | 'preview' | 'canary' | 'release'
2+
13
export interface BuildInfo {
24
version: string
35
commit: string
46
shortCommit: string
57
time: number
68
branch: string
7-
env: 'preview' | 'canary' | 'dev' | 'release'
9+
env: EnvType
810
privacyPolicyDate: string
911
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { mountSuspended } from '@nuxt/test-utils/runtime'
3+
import AppFooter from '~/components/AppFooter.vue'
4+
5+
/* check nuxt module at modules/build-env.ts */
6+
describe('AppFooter', () => {
7+
it('BuildEnvironment is properly displayed at settings', async () => {
8+
const buildInfo = useAppConfig().buildInfo
9+
const component = await mountSuspended(AppFooter, {
10+
route: '/settings',
11+
})
12+
13+
const envSpan = component.find('span.tracking-wider')
14+
expect(envSpan.exists()).toBe(true)
15+
expect(envSpan.text()).toBe(buildInfo.env)
16+
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
17+
expect(commitLink.exists()).toBe(true)
18+
const tagLink = component.find(`a[href$="/tag/v${buildInfo.version}"]`)
19+
expect(tagLink.exists()).toBe(false)
20+
})
21+
22+
it('BuildEnvironment is hidden at home', async () => {
23+
const buildInfo = useAppConfig().buildInfo
24+
const component = await mountSuspended(AppFooter, {
25+
route: '/',
26+
})
27+
28+
const envSpan = component.find('span.tracking-wider')
29+
expect(envSpan.exists()).toBe(false)
30+
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
31+
expect(commitLink.exists()).toBe(false)
32+
const tagLink = component.find(`a[href$="/tag/v${buildInfo.version}"]`)
33+
expect(tagLink.exists()).toBe(false)
34+
})
35+
})
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import type { BuildInfo } from '#shared/types'
2+
import { describe, expect, it } from 'vitest'
3+
import { mountSuspended } from '@nuxt/test-utils/runtime'
4+
import BuildEnvironment from '~/components/BuildEnvironment.vue'
5+
6+
describe('BuildEnvironment', () => {
7+
it('renders dev environment correctly', async () => {
8+
const buildInfo: BuildInfo = {
9+
env: 'dev',
10+
version: '1.2.3',
11+
time: 1234567890,
12+
commit: 'abcdef',
13+
shortCommit: 'abc',
14+
branch: 'main',
15+
privacyPolicyDate: new Date().toISOString(),
16+
}
17+
const component = await mountSuspended(BuildEnvironment, {
18+
props: {
19+
buildInfo,
20+
},
21+
})
22+
23+
// In dev mode, it shows env name, not version link
24+
const envSpan = component.find('span.tracking-wider')
25+
expect(envSpan.exists()).toBe(true)
26+
expect(envSpan.text()).toBe(buildInfo.env)
27+
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
28+
expect(commitLink.exists()).toBe(true)
29+
const tagLink = component.find(`a[href$="/tag/v${buildInfo.version}"]`)
30+
expect(tagLink.exists()).toBe(false)
31+
})
32+
33+
it('renders release environment correctly', async () => {
34+
const buildInfo: BuildInfo = {
35+
env: 'release',
36+
version: '1.2.3',
37+
time: 1234567890,
38+
commit: 'abcdef',
39+
shortCommit: 'abc',
40+
branch: 'release',
41+
privacyPolicyDate: new Date().toISOString(),
42+
}
43+
44+
const component = await mountSuspended(BuildEnvironment, {
45+
props: {
46+
buildInfo,
47+
},
48+
})
49+
50+
// In release mode, it shows tag version link, not env name
51+
const envSpan = component.find('span.tracking-wider')
52+
expect(envSpan.exists()).toBe(false)
53+
const commitLink = component.find(`a[href$="/commit/${buildInfo.commit}"]`)
54+
expect(commitLink.exists()).toBe(false)
55+
const tagLink = component.find(`a[href$="/tag/v${buildInfo.version}"]`)
56+
expect(tagLink.exists()).toBe(true)
57+
})
58+
})

0 commit comments

Comments
 (0)