From 80bf4bc019a39d1ed9b68848bf75c2573242266e Mon Sep 17 00:00:00 2001 From: webmaster Date: Tue, 3 Nov 2026 14:12:01 +0000 Subject: [PATCH] fix(freelancer-directory): the clients filter is a yes/all facet, the dropdowns are 30% narrower, the badge is opaque and inset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Clients on ODOO4projects" filter was a numeric minimum (data-match="min", "4+ clients"). Both live records carry the same count, so no threshold could ever narrow it — it was dead on live data. Replaced with one two-option control, All "" / Yes "yes", and the test is now "has a count above zero". The threshold machinery (data-match="min" and its numeric branch) is dropped from both renderers and from build-directory.py. A facet is still printed only when the data supports it: the yes/all control renders only when a record with a count and a record without one (0 or absent) both exist — otherwise "Yes" and "All" return the same list. With today's two live records (counts 2 and 4) it therefore does not print; it appears by itself the moment a zero lands. The four dropdown boxes are 30% narrower: .dir-filter:has(> select) min-width 180px -> 126px, so only the facets change width. */ + .dir-filter:has(> select) { + min-width: 126px; + } .dir-filter label { font-size: 0.78rem; letter-spacing: 0.04em; @@ -687,26 +693,27 @@ } /* The OCA Member Profile badge — a link built from a link the freelancer - supplied. It straddles the card's frame at the top-right corner: the top - and right border lines run through it, like a tag on the corner, rather - than sitting inside the frame. It stays in the DOM with the name (the name - is read first). Never colour alone: it is a filled pill and its own words - are the link text. */ + supplied. It straddles the card's TOP frame at the top-right corner (the top + border line runs through it, like a tag on the corner) but its RIGHT edge sits + inside the frame with a clear gap, not over the right border. Solid brass fill, + never a translucent pill. It stays in the DOM with the name (the name is read + first). Never colour alone: it is a filled pill and its own words are the link + text. */ .dev-oca-badge { position: absolute; top: -0.7rem; /* half the pill sits above the card's top border */ - right: -0.55rem; /* a little hangs past the right border — a corner tag */ + right: 0.5rem; /* inside the right border, an 8px gap to it */ font-size: 0.72rem; line-height: 1.4; padding: 0.15rem 0.6rem; border-radius: var(--radius-pill, 999px); - background: rgba(201, 162, 39, 0.2); + background: var(--brass); /* opaque — was rgba(201,162,39,0.2) */ border: 1px solid var(--brass-deep); - color: var(--midnight); + color: var(--midnight); /* 7.16:1 on the solid brass fill */ font-weight: 600; } .dev-oca-badge:hover { - background: rgba(201, 162, 39, 0.32); + background: var(--brass-bright); color: var(--midnight); } @@ -966,7 +973,6 @@
-
@@ -975,7 +981,7 @@
-
+
@@ -986,7 +992,7 @@

ginwwgnri

No contact details published for this freelancer.

-
+
@@ -1798,7 +1804,7 @@ ["Country", "Country", "country", "value"], ["__langs__", "Language", "languages", "langnum"], ["__oca__", "OCA member", "oca", "oca"], - ["odoo4projects_clients", "Clients on ODOO4projects", "clients", "min"] + ["odoo4projects_clients", "Clients on ODOO4projects", "clients", "yes"] ]; var LIVE_ALIASES = { Country: ["country"] }; @@ -1899,9 +1905,11 @@ function liveAttrValue(rec, pair) { var field = pair[0], kind = pair[3]; - if (kind === "min") { + if (kind === "yes") { + // "Has clients on ODOO4projects": a count above zero. A 0 or an absent + // count is the empty value, so the card drops out on "Yes". var n = parseInt(rec[field], 10); - return isNaN(n) ? "" : String(n); + return (isNaN(n) || n <= 0) ? "" : "yes"; } if (kind === "oca") return liveOcaLink(rec) ? "1" : ""; if (kind === "langnum") return liveLangsDeclared(rec).map(fold).join("|"); @@ -2050,16 +2058,15 @@ var field = pair[0], label = pair[1], attr = pair[2], kind = pair[3]; var options = null; - if (kind === "min") { - var counts = []; + if (kind === "yes") { + // Print only when the list holds both kinds of record — one with clients and + // one without — so the facet can actually narrow. "Yes" == "All" otherwise. + var hasYes = false, hasNo = false; records.forEach(function (r) { var n = parseInt(r[field], 10); - if (!isNaN(n) && counts.indexOf(n) === -1) counts.push(n); + if (!isNaN(n) && n > 0) hasYes = true; else hasNo = true; }); - counts.sort(function (a, b) { return a - b; }); - if (counts.length >= 2) { - options = counts.slice(1).map(function (c) { return [String(c), c + "+ clients"]; }); - } + if (hasYes && hasNo) options = [["yes", "Yes"]]; } else if (kind === "oca") { if (records.some(function (r) { return liveOcaLink(r); })) { options = [["1", "OCA member"]]; @@ -2100,7 +2107,6 @@ var sel = document.createElement("select"); sel.id = id; sel.setAttribute("data-field", attr); - if (kind === "min") sel.setAttribute("data-match", "min"); sel.appendChild(new Option("All", "")); options.forEach(function (o) { sel.appendChild(new Option(o[1], o[0])); }); wrap.appendChild(lbl); @@ -2185,12 +2191,9 @@ var want = sel.value; if (!want) return; var have = card.getAttribute("data-" + sel.getAttribute("data-field")) || ""; - if (sel.getAttribute("data-match") === "min") { - var n = parseInt(have, 10); - if (isNaN(n) || n < parseInt(want, 10)) ok = false; - } else if (have.split("|").indexOf(want) === -1) { - ok = false; - } + // Every facet is an exact membership test against the card's value — + // including "yes" (the card carries "yes" only for a count above zero). + if (have.split("|").indexOf(want) === -1) ok = false; }); } card.hidden = !ok;