fix(manager): favorites filter as wp-input box matching prototype
Replace chip-toggle approach with the correct prototype pattern: a button.wp-input containing an inline wp-check span, styled identically to the Category Select in the same 2-column filter grid. Clicking the whole bordered box toggles the favorites filter. Uses span.wp-check (visual-only) to avoid invalid button-in-button HTML nesting. Reverts intermediate chip approach.
This commit is contained in:
@@ -119,11 +119,9 @@ describe("ModuleListView.vue", () => {
|
||||
await filtersBtn.trigger("click");
|
||||
await flushPromises();
|
||||
expect(wrap.find(".wp-filter-panel").exists()).toBe(true);
|
||||
// Favorites quick-filter chip and extra-filter chips are both rendered.
|
||||
const toggleChips = wrap.findAll(".wp-chip--toggle");
|
||||
expect(toggleChips.length).toBeGreaterThanOrEqual(2);
|
||||
expect(toggleChips.some((c) => c.text().includes("Favorites only"))).toBe(true);
|
||||
expect(toggleChips.some((c) => c.text().includes("Favorited"))).toBe(true);
|
||||
// Extra filter chip is rendered inside.
|
||||
expect(wrap.find(".wp-chip--toggle").exists()).toBe(true);
|
||||
expect(wrap.find(".wp-chip--toggle").text()).toContain("Favorited");
|
||||
});
|
||||
|
||||
it("paginates 20 items into pages of 10 then 10 when pageSize=10", async () => {
|
||||
|
||||
@@ -354,19 +354,6 @@ defineExpose({
|
||||
<Transition name="filter-collapse">
|
||||
<div v-if="filtersOpen" class="wp-filter-panel">
|
||||
<slot name="filter-panel" :filter="filter" :emit-fetch="emitFetch" />
|
||||
<div v-if="showFavorite" class="wp-filter-panel__extra">
|
||||
<span class="wp-filter-panel__extra-label">Quick filters</span>
|
||||
<div class="wp-filter-panel__extra-chips">
|
||||
<button
|
||||
type="button"
|
||||
class="wp-chip wp-chip--toggle"
|
||||
:data-active="filter.favorites ? '' : null"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
★ Favorites only
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="extraFilters?.length" class="wp-filter-panel__extra">
|
||||
<span class="wp-filter-panel__extra-label">Syntax</span>
|
||||
<div class="wp-filter-panel__extra-chips">
|
||||
|
||||
@@ -151,7 +151,22 @@ function templateParts(row: ModuleRow): TemplatePart[] {
|
||||
@update:model-value="(v) => { filter.category = v as string | null; emitFetch(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="wp-field">
|
||||
<label class="wp-field__label">Favorites</label>
|
||||
<button
|
||||
type="button"
|
||||
class="wp-input"
|
||||
style="display:flex;align-items:center;gap:8px;justify-content:flex-start;"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
<span class="wp-check" :data-checked="filter.favorites ? 'true' : 'false'" aria-hidden="true">
|
||||
<svg v-if="filter.favorites" viewBox="0 0 12 12" fill="none" style="display:block">
|
||||
<path d="M3 6.2l2.2 2.2L9 4.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>Favorites only</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="wp-field wp-field--full">
|
||||
<label class="wp-field__label">
|
||||
Tags{{ filter.tags?.length ? ` (${filter.tags.length})` : "" }}
|
||||
|
||||
@@ -187,7 +187,22 @@ function formatFactor(f: number): string {
|
||||
@update:model-value="(v) => { filter.category = v as string | null; emitFetch(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="wp-field">
|
||||
<label class="wp-field__label">Favorites</label>
|
||||
<button
|
||||
type="button"
|
||||
class="wp-input"
|
||||
style="display:flex;align-items:center;gap:8px;justify-content:flex-start;"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
<span class="wp-check" :data-checked="filter.favorites ? 'true' : 'false'" aria-hidden="true">
|
||||
<svg v-if="filter.favorites" viewBox="0 0 12 12" fill="none" style="display:block">
|
||||
<path d="M3 6.2l2.2 2.2L9 4.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>Favorites only</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="wp-field wp-field--full">
|
||||
<label class="wp-field__label">
|
||||
Tags{{ filter.tags?.length ? ` (${filter.tags.length})` : "" }}
|
||||
|
||||
@@ -151,7 +151,22 @@ function actView(a: DerivationAction | undefined): { verb: string; target: strin
|
||||
@update:model-value="(v) => { filter.category = v as string | null; emitFetch(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="wp-field">
|
||||
<label class="wp-field__label">Favorites</label>
|
||||
<button
|
||||
type="button"
|
||||
class="wp-input"
|
||||
style="display:flex;align-items:center;gap:8px;justify-content:flex-start;"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
<span class="wp-check" :data-checked="filter.favorites ? 'true' : 'false'" aria-hidden="true">
|
||||
<svg v-if="filter.favorites" viewBox="0 0 12 12" fill="none" style="display:block">
|
||||
<path d="M3 6.2l2.2 2.2L9 4.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>Favorites only</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="wp-field wp-field--full">
|
||||
<label class="wp-field__label">
|
||||
Tags{{ filter.tags?.length ? ` (${filter.tags.length})` : "" }}
|
||||
|
||||
@@ -127,7 +127,22 @@ function topValues(row: ModuleRow): NamedValue[] { return values(row).slice(0, 4
|
||||
@update:model-value="(v) => { filter.category = v as string | null; emitFetch(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="wp-field">
|
||||
<label class="wp-field__label">Favorites</label>
|
||||
<button
|
||||
type="button"
|
||||
class="wp-input"
|
||||
style="display:flex;align-items:center;gap:8px;justify-content:flex-start;"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
<span class="wp-check" :data-checked="filter.favorites ? 'true' : 'false'" aria-hidden="true">
|
||||
<svg v-if="filter.favorites" viewBox="0 0 12 12" fill="none" style="display:block">
|
||||
<path d="M3 6.2l2.2 2.2L9 4.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>Favorites only</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="wp-field wp-field--full">
|
||||
<label class="wp-field__label">
|
||||
Tags{{ filter.tags?.length ? ` (${filter.tags.length})` : "" }}
|
||||
|
||||
@@ -197,7 +197,22 @@ function pad2(n: number): string { return String(n + 1).padStart(2, "0"); }
|
||||
@update:model-value="(v) => { filter.category = v as string | null; emitFetch(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="wp-field">
|
||||
<label class="wp-field__label">Favorites</label>
|
||||
<button
|
||||
type="button"
|
||||
class="wp-input"
|
||||
style="display:flex;align-items:center;gap:8px;justify-content:flex-start;"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
<span class="wp-check" :data-checked="filter.favorites ? 'true' : 'false'" aria-hidden="true">
|
||||
<svg v-if="filter.favorites" viewBox="0 0 12 12" fill="none" style="display:block">
|
||||
<path d="M3 6.2l2.2 2.2L9 4.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>Favorites only</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="wp-field wp-field--full">
|
||||
<label class="wp-field__label">
|
||||
Tags{{ filter.tags?.length ? ` (${filter.tags.length})` : "" }}
|
||||
|
||||
@@ -187,7 +187,22 @@ function isValid(row: ModuleRow): boolean {
|
||||
@update:model-value="(v) => { filter.category = v as string | null; emitFetch(); }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="wp-field">
|
||||
<label class="wp-field__label">Favorites</label>
|
||||
<button
|
||||
type="button"
|
||||
class="wp-input"
|
||||
style="display:flex;align-items:center;gap:8px;justify-content:flex-start;"
|
||||
@click="filter.favorites = !filter.favorites; emitFetch()"
|
||||
>
|
||||
<span class="wp-check" :data-checked="filter.favorites ? 'true' : 'false'" aria-hidden="true">
|
||||
<svg v-if="filter.favorites" viewBox="0 0 12 12" fill="none" style="display:block">
|
||||
<path d="M3 6.2l2.2 2.2L9 4.4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span>Favorites only</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="wp-field wp-field--full">
|
||||
<label class="wp-field__label">
|
||||
Tags{{ filter.tags?.length ? ` (${filter.tags.length})` : "" }}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/wp/images/favicon.svg" />
|
||||
<link rel="apple-touch-icon" href="/wp/images/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/wp/images/site.webmanifest" />
|
||||
<script type="module" crossorigin src="/wp/assets/manager-baYgQ7LG.js"></script>
|
||||
<script type="module" crossorigin src="/wp/assets/manager-BWnFunYr.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/wp/assets/manager-C6od6CgI.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user