fix config ui

This commit is contained in:
Julian Freeman
2026-04-16 21:50:32 -04:00
parent 83f762435b
commit 189d7c02f5

View File

@@ -37,139 +37,146 @@ const iconOptions = computed(() =>
</script> </script>
<template> <template>
<section class="content-scroll-area"> <section class="config-page styled-scrollbar">
<section class="content-section"> <div v-if="configError" class="inline-error">
<div v-if="configError" class="inline-error"> {{ configError }}
{{ configError }} </div>
</div>
<div class="config-form-card"> <div class="config-form-card">
<div class="config-form-header collapsible"> <div class="config-form-header collapsible">
<div> <div>
<h3>Add Custom Browser</h3> <h3>Add Custom Browser</h3>
<p>Add a custom executable and Chromium user data path when needed.</p> <p>Add a custom executable and Chromium user data path when needed.</p>
</div>
<button
class="secondary-button config-toggle-button"
type="button"
@click="formExpanded = !formExpanded"
>
{{ formExpanded ? "Collapse" : "Expand" }}
</button>
</div>
<div v-if="formExpanded" class="config-form-fields compact">
<div class="config-inline-row">
<label class="field-group">
<span>Name</span>
<input
:value="createConfigForm.name"
placeholder="Work Chrome"
@input="emit('updateName', ($event.target as HTMLInputElement).value)"
/>
</label>
<label class="field-group">
<span>Icon</span>
<SortDropdown
:model-value="createConfigForm.iconKey ?? 'chrome'"
:options="iconOptions"
@update:model-value="emit('updateIconKey', $event)"
/>
</label>
</div>
<label class="field-group">
<span>Executable Path</span>
<div class="path-input-row">
<input
:value="createConfigForm.executablePath"
placeholder="C:\Program Files\...\chrome.exe"
@input="emit('updateExecutablePath', ($event.target as HTMLInputElement).value)"
/>
<button class="secondary-button" type="button" @click="emit('pickExecutablePath')">
Browse File
</button>
</div> </div>
</label>
<label class="field-group">
<span>User Data Path</span>
<div class="path-input-row">
<input
:value="createConfigForm.userDataPath"
placeholder="C:\Users\...\User Data"
@input="emit('updateUserDataPath', ($event.target as HTMLInputElement).value)"
/>
<button class="secondary-button" type="button" @click="emit('pickUserDataPath')">
Browse Folder
</button>
</div>
</label>
<div class="config-form-actions">
<button <button
class="secondary-button config-toggle-button" class="primary-button"
type="button" type="button"
@click="formExpanded = !formExpanded" :disabled="savingConfig"
@click="emit('createConfig')"
> >
{{ formExpanded ? "Collapse" : "Expand" }} {{ savingConfig ? "Saving..." : "Add Config" }}
</button> </button>
</div> </div>
<div v-if="formExpanded" class="config-form-fields compact">
<div class="config-inline-row">
<label class="field-group">
<span>Name</span>
<input
:value="createConfigForm.name"
placeholder="Work Chrome"
@input="emit('updateName', ($event.target as HTMLInputElement).value)"
/>
</label>
<label class="field-group">
<span>Icon</span>
<SortDropdown
:model-value="createConfigForm.iconKey ?? 'chrome'"
:options="iconOptions"
@update:model-value="emit('updateIconKey', $event)"
/>
</label>
</div>
<label class="field-group">
<span>Executable Path</span>
<div class="path-input-row">
<input
:value="createConfigForm.executablePath"
placeholder="C:\Program Files\...\chrome.exe"
@input="emit('updateExecutablePath', ($event.target as HTMLInputElement).value)"
/>
<button class="secondary-button" type="button" @click="emit('pickExecutablePath')">
Browse File
</button>
</div>
</label>
<label class="field-group">
<span>User Data Path</span>
<div class="path-input-row">
<input
:value="createConfigForm.userDataPath"
placeholder="C:\Users\...\User Data"
@input="emit('updateUserDataPath', ($event.target as HTMLInputElement).value)"
/>
<button class="secondary-button" type="button" @click="emit('pickUserDataPath')">
Browse Folder
</button>
</div>
</label>
<div class="config-form-actions">
<button
class="primary-button"
type="button"
:disabled="savingConfig"
@click="emit('createConfig')"
>
{{ savingConfig ? "Saving..." : "Add Config" }}
</button>
</div>
</div>
<div v-else class="config-form-collapsed-note">
<span>Collapsed by default to keep this page focused on existing configs.</span>
</div>
</div> </div>
<div v-else class="config-form-collapsed-note">
<span>Collapsed by default to keep this page focused on existing configs.</span>
</div>
</div>
<div v-if="configsLoading" class="empty-card"> <div v-if="configsLoading" class="empty-card">
<p>Loading browser configs...</p> <p>Loading browser configs...</p>
</div> </div>
<div v-else class="stack-list"> <div v-else class="stack-list">
<article <article
v-for="config in browserConfigs" v-for="config in browserConfigs"
:key="config.id" :key="config.id"
class="config-card" class="config-card"
> >
<div class="config-card-header"> <div class="config-card-header">
<div class="config-card-lead"> <div class="config-card-lead">
<div class="browser-nav-icon config-icon"> <div class="browser-nav-icon config-icon">
<img <img
v-if="browserIconSrc(config.iconKey ?? config.browserFamilyId)" v-if="browserIconSrc(config.iconKey ?? config.browserFamilyId)"
:src="browserIconSrc(config.iconKey ?? config.browserFamilyId) ?? undefined" :src="browserIconSrc(config.iconKey ?? config.browserFamilyId) ?? undefined"
:alt="`${config.name} icon`" :alt="`${config.name} icon`"
/> />
<span v-else>{{ configMonogram(config) }}</span> <span v-else>{{ configMonogram(config) }}</span>
</div> </div>
<div> <div>
<div class="config-title-row"> <div class="config-title-row">
<h4>{{ config.name }}</h4> <h4>{{ config.name }}</h4>
</div>
</div> </div>
</div> </div>
<button
v-if="config.deletable"
class="danger-button"
type="button"
:disabled="isDeletingConfig(config.id)"
@click="emit('deleteConfig', config.id)"
>
{{ isDeletingConfig(config.id) ? "Deleting..." : "Delete" }}
</button>
</div> </div>
<div class="config-meta"> <button
<div class="config-meta-row"> v-if="config.deletable"
<span class="config-label">Executable</span> class="danger-button"
<p :title="config.executablePath">{{ config.executablePath || "Not resolved" }}</p> type="button"
</div> :disabled="isDeletingConfig(config.id)"
<div class="config-meta-row"> @click="emit('deleteConfig', config.id)"
<span class="config-label">User Data</span> >
<p :title="config.userDataPath">{{ config.userDataPath }}</p> {{ isDeletingConfig(config.id) ? "Deleting..." : "Delete" }}
</div> </button>
</div>
<div class="config-meta">
<div class="config-meta-row">
<span class="config-label">Executable</span>
<p :title="config.executablePath">{{ config.executablePath || "Not resolved" }}</p>
</div> </div>
</article> <div class="config-meta-row">
</div> <span class="config-label">User Data</span>
</section> <p :title="config.userDataPath">{{ config.userDataPath }}</p>
</div>
</div>
</article>
</div>
</section> </section>
</template> </template>
<style scoped> <style scoped>
.config-page {
display: flex;
flex-direction: column;
gap: 10px;
min-height: 0;
overflow: auto;
padding: 0 2px 0 0;
}
.config-form-card, .config-form-card,
.config-card { .config-card {
border-radius: 18px; border-radius: 18px;