fix(ui): keep Bitcoin version choices readable in kiosk
This commit is contained in:
@@ -25,13 +25,22 @@
|
|||||||
<div v-if="loading" class="py-6 text-center text-white/60 text-sm">{{ t('common.loading') }}</div>
|
<div v-if="loading" class="py-6 text-center text-white/60 text-sm">{{ t('common.loading') }}</div>
|
||||||
|
|
||||||
<div v-else class="space-y-2">
|
<div v-else class="space-y-2">
|
||||||
<label class="block text-white/60 text-sm">{{ t('appDetails.selectVersion') }}</label>
|
<fieldset class="space-y-2">
|
||||||
<select
|
<legend class="text-white/60 text-sm mb-2">{{ t('appDetails.selectVersion') }}</legend>
|
||||||
v-model="selected"
|
<!-- Inline options avoid native popup rendering in the kiosk WebView.
|
||||||
class="w-full rounded-lg bg-white/[0.06] border border-white/10 text-white pl-3 pr-9 py-2 text-sm focus:outline-none focus:border-blue-400/60"
|
They stay in document flow above the pruning explanation. -->
|
||||||
|
<div class="max-h-40 overflow-y-auto space-y-2 rounded-lg">
|
||||||
|
<label
|
||||||
|
v-for="v in versions"
|
||||||
|
:key="v.version"
|
||||||
|
class="flex items-center gap-3 rounded-lg border px-3 py-2.5 text-sm text-white cursor-pointer"
|
||||||
|
:class="selected === v.version ? 'border-blue-400/60 bg-slate-800' : 'border-white/10 bg-slate-900'"
|
||||||
>
|
>
|
||||||
<option v-for="v in versions" :key="v.version" :value="v.version">{{ optionLabel(v) }}</option>
|
<input v-model="selected" type="radio" :name="`install-version-${appId}`" :value="v.version" class="shrink-0 accent-blue-400" />
|
||||||
</select>
|
<span>{{ optionLabel(v) }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
<p class="text-white/40 text-xs">{{ t('marketplace.installModalHint') }}</p>
|
<p class="text-white/40 text-xs">{{ t('marketplace.installModalHint') }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -113,6 +122,7 @@ async function load() {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (import.meta.env.DEV) console.warn('[InstallVersionModal] getPackageVersions failed:', err)
|
if (import.meta.env.DEV) console.warn('[InstallVersionModal] getPackageVersions failed:', err)
|
||||||
// Fall back to the floating "latest" so the install can still proceed.
|
// Fall back to the floating "latest" so the install can still proceed.
|
||||||
|
versions.value = [{ version: 'latest' } as CatalogVersionInfo]
|
||||||
selected.value = 'latest'
|
selected.value = 'latest'
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ describe('Bitcoin install storage choice', () => {
|
|||||||
versions.mockResolvedValue({ bitcoinPrune: false, default: 'latest', versions: [{ version: 'latest' }, { version: '28.4' }] })
|
versions.mockResolvedValue({ bitcoinPrune: false, default: 'latest', versions: [{ version: 'latest' }, { version: '28.4' }] })
|
||||||
const wrapper = modal(id)
|
const wrapper = modal(id)
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
await wrapper.get('select').setValue('28.4')
|
await wrapper.get('input[type=radio][value="28.4"]').setValue(true)
|
||||||
await wrapper.get('input[type=checkbox]').setValue(true)
|
await wrapper.get('input[type=checkbox]').setValue(true)
|
||||||
await wrapper.get('button').trigger('click')
|
await wrapper.get('button').trigger('click')
|
||||||
expect(wrapper.emitted('confirm')).toEqual([['28.4', true]])
|
expect(wrapper.emitted('confirm')).toEqual([['28.4', true]])
|
||||||
expect(wrapper.text()).toContain('automatic pruning')
|
expect(wrapper.text()).toContain('automatic pruning')
|
||||||
expect(wrapper.text()).toContain('Mempool')
|
expect(wrapper.text()).toContain('Mempool')
|
||||||
|
expect(wrapper.find('select').exists()).toBe(false)
|
||||||
|
expect(wrapper.findAll('input[type=radio]')).toHaveLength(2)
|
||||||
})
|
})
|
||||||
it('keeps automatic disk selection by default and resets on reopening', async () => {
|
it('keeps automatic disk selection by default and resets on reopening', async () => {
|
||||||
versions.mockResolvedValue({ bitcoinPrune: false, versions: [{ version: 'latest' }] })
|
versions.mockResolvedValue({ bitcoinPrune: false, versions: [{ version: 'latest' }] })
|
||||||
@@ -29,17 +31,17 @@ describe('Bitcoin install storage choice', () => {
|
|||||||
await flushPromises()
|
await flushPromises()
|
||||||
await wrapper.get('button').trigger('click')
|
await wrapper.get('button').trigger('click')
|
||||||
expect(wrapper.emitted('confirm')).toEqual([['latest', false]])
|
expect(wrapper.emitted('confirm')).toEqual([['latest', false]])
|
||||||
await wrapper.get('input').setValue(true)
|
await wrapper.get('input[type=checkbox]').setValue(true)
|
||||||
await wrapper.setProps({ show: false })
|
await wrapper.setProps({ show: false })
|
||||||
await wrapper.setProps({ show: true })
|
await wrapper.setProps({ show: true })
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect((wrapper.get('input').element as HTMLInputElement).checked).toBe(false)
|
expect((wrapper.get('input[type=checkbox]').element as HTMLInputElement).checked).toBe(false)
|
||||||
})
|
})
|
||||||
it('still allows choosing pruning when version lookup fails', async () => {
|
it('still allows choosing pruning when version lookup fails', async () => {
|
||||||
versions.mockRejectedValue(new Error('offline'))
|
versions.mockRejectedValue(new Error('offline'))
|
||||||
const wrapper = modal()
|
const wrapper = modal()
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
await wrapper.get('input').setValue(true)
|
await wrapper.get('input[type=checkbox]').setValue(true)
|
||||||
await wrapper.get('button').trigger('click')
|
await wrapper.get('button').trigger('click')
|
||||||
expect(wrapper.emitted('confirm')).toEqual([['latest', true]])
|
expect(wrapper.emitted('confirm')).toEqual([['latest', true]])
|
||||||
})
|
})
|
||||||
@@ -47,7 +49,7 @@ describe('Bitcoin install storage choice', () => {
|
|||||||
versions.mockResolvedValue({ bitcoinPrune: true, versions: [{ version: 'latest' }] })
|
versions.mockResolvedValue({ bitcoinPrune: true, versions: [{ version: 'latest' }] })
|
||||||
const wrapper = modal('bitcoin-knots')
|
const wrapper = modal('bitcoin-knots')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect((wrapper.get('input').element as HTMLInputElement).checked).toBe(true)
|
expect((wrapper.get('input[type=checkbox]').element as HTMLInputElement).checked).toBe(true)
|
||||||
await wrapper.get('button').trigger('click')
|
await wrapper.get('button').trigger('click')
|
||||||
expect(wrapper.emitted('confirm')).toEqual([['latest', true]])
|
expect(wrapper.emitted('confirm')).toEqual([['latest', true]])
|
||||||
})
|
})
|
||||||
@@ -62,6 +64,6 @@ describe('Bitcoin install storage choice', () => {
|
|||||||
versions.mockResolvedValue({ bitcoinPrune: false, versions: [{ version: 'latest' }] })
|
versions.mockResolvedValue({ bitcoinPrune: false, versions: [{ version: 'latest' }] })
|
||||||
const wrapper = modal('other')
|
const wrapper = modal('other')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
expect(wrapper.find('input').exists()).toBe(false)
|
expect(wrapper.find('input[type=checkbox]').exists()).toBe(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user