Public Access
fix(freelancer): the 15-point rule is now one shared constant, in both forms
The edit form's legend read "Skill areas" and carried no directive, while the application form read "Skill profile — 15 points to distribute" and said what to do. Same rule, worded in two places — and the edit form lost the sentence. - New static/focus-rule.js exposes window.O4PFocus: LEGEND, DIRECTIVE, TOTAL, MAX and message(sum). Both forms render the legend, the directive and the wrong-total message from it, so the two cannot drift apart again. - Edit form: legend from the constant, the application form's directive under it, and the blocked-save message now names the direction. - Application form: legend set from the constant, live warn and sum gate use the same message(); the all-zero gate keeps the directive. - Message wording: over -> "remove N", under -> "add N", zero -> "place all 15 points"; the total, aria-live, data-bad, the blocked save and the fieldset/legend structure are unchanged. The rule text now appears once: "You have 17 of 15 — remove 2."
This commit is contained in:
1 parent
1a1b62136f
commit
768dc1151a
3 files changed
+40
-22
No files matched your search
@@ -146,6 +146,9 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- The 15-point rule, in ONE copy for both forms (this one and the application form). -->
|
||||||
|
<script src="/static/focus-rule.js"></script>
|
||||||
|
|
||||||
<!-- 1) Read the credential, then take it OUT of the address bar.
|
<!-- 1) Read the credential, then take it OUT of the address bar.
|
||||||
The hash arrives as ?has=... or ?hash=... (both spellings accepted, 'has' first — the
|
The hash arrives as ?has=... or ?hash=... (both spellings accepted, 'has' first — the
|
||||||
same list the answer page reads, so the two emailed links behave identically). The page
|
same list the answer page reads, so the two emailed links behave identically). The page
|
||||||
@@ -186,7 +189,7 @@
|
|||||||
functional: "Functional", system: "System", modules: "Modules",
|
functional: "Functional", system: "System", modules: "Modules",
|
||||||
integration: "Integration", ai: "AI"
|
integration: "Integration", ai: "AI"
|
||||||
},
|
},
|
||||||
focusTotal: 15,
|
focusTotal: window.O4PFocus.TOTAL,
|
||||||
focusMax: 5,
|
focusMax: 5,
|
||||||
focusMaxChars: 70,
|
focusMaxChars: 70,
|
||||||
descMaxChars: 230,
|
descMaxChars: 230,
|
||||||
@@ -256,6 +259,7 @@
|
|||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var C = window.O4E;
|
var C = window.O4E;
|
||||||
|
var CG = window.O4PFocus; // the shared 15-point rule (static/focus-rule.js)
|
||||||
var app = document.getElementById("app");
|
var app = document.getElementById("app");
|
||||||
var hash = window.__EDIT_HASH || "";
|
var hash = window.__EDIT_HASH || "";
|
||||||
var rec = null; // this person's record, once loaded
|
var rec = null; // this person's record, once loaded
|
||||||
@@ -496,7 +500,9 @@
|
|||||||
// The five axes. An axis the record does not carry keeps the application form's
|
// The five axes. An axis the record does not carry keeps the application form's
|
||||||
// default of 3, so the block always totals 15 and can be saved.
|
// default of 3, so the block always totals 15 and can be saved.
|
||||||
var axesSet = el("fieldset", "");
|
var axesSet = el("fieldset", "");
|
||||||
axesSet.appendChild(el("legend", "", "Skill areas"));
|
axesSet.appendChild(el("legend", "", CG.LEGEND));
|
||||||
|
// The same directive the application form carries, so both forms state the rule.
|
||||||
|
axesSet.appendChild(el("p", "hint", CG.DIRECTIVE));
|
||||||
C.focusAxes.forEach(function (axis) {
|
C.focusAxes.forEach(function (axis) {
|
||||||
var v = readField(record, axis);
|
var v = readField(record, axis);
|
||||||
if (v === undefined || v === null || v === "") v = 3; // → the block totals 15
|
if (v === undefined || v === null || v === "") v = 3; // → the block totals 15
|
||||||
@@ -556,8 +562,7 @@
|
|||||||
if (focusSum() !== C.focusTotal) {
|
if (focusSum() !== C.focusTotal) {
|
||||||
var sum = focusSum();
|
var sum = focusSum();
|
||||||
line.className = "status state-err";
|
line.className = "status state-err";
|
||||||
line.textContent = "The five skill numbers total " + sum + ". They must total exactly " +
|
line.textContent = CG.message(sum); // names the direction: remove / add / place all
|
||||||
C.focusTotal + " before this can be saved.";
|
|
||||||
focusTotalLine.setAttribute("data-bad", "1");
|
focusTotalLine.setAttribute("data-bad", "1");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1949,6 +1949,7 @@
|
|||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script defer src="/static/lang.js"></script>
|
<script defer src="/static/lang.js"></script>
|
||||||
|
<script src="/static/focus-rule.js"></script>
|
||||||
<script>
|
<script>
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
Odoo freelancer directory — page script.
|
Odoo freelancer directory — page script.
|
||||||
@@ -1994,8 +1995,8 @@
|
|||||||
// The five self-assessed focus axes — each a SEPARATE numeric field (0-5) on the
|
// The five self-assessed focus axes — each a SEPARATE numeric field (0-5) on the
|
||||||
// wire, no CSV, no encoding. They must total exactly FOCUS_TOTAL.
|
// wire, no CSV, no encoding. They must total exactly FOCUS_TOTAL.
|
||||||
var FOCUS_AXES = ["functional", "system", "modules", "integration", "ai"];
|
var FOCUS_AXES = ["functional", "system", "modules", "integration", "ai"];
|
||||||
var FOCUS_TOTAL = 15;
|
var FOCUS_TOTAL = O4PFocus.TOTAL; // the shared rule (static/focus-rule.js)
|
||||||
var FOCUS_MAX = 5;
|
var FOCUS_MAX = O4PFocus.MAX;
|
||||||
var FOCUS_AXIS_LABELS = {
|
var FOCUS_AXIS_LABELS = {
|
||||||
functional: "Functional", system: "System", modules: "Modules",
|
functional: "Functional", system: "System", modules: "Modules",
|
||||||
integration: "Integration", ai: "AI"
|
integration: "Integration", ai: "AI"
|
||||||
@@ -2089,22 +2090,17 @@
|
|||||||
savable — an all-zero block is simply left unsent). */
|
savable — an all-zero block is simply left unsent). */
|
||||||
function focusError(form, required) {
|
function focusError(form, required) {
|
||||||
var sum = focusSum(form);
|
var sum = focusSum(form);
|
||||||
if (sum === 0) {
|
if (sum === 0) return required ? O4PFocus.DIRECTIVE : "";
|
||||||
return required
|
return O4PFocus.message(sum); // "" when right; names the direction when not
|
||||||
? "Distribute all 15 points across the five areas — they cannot all be 0."
|
|
||||||
: "";
|
|
||||||
}
|
|
||||||
if (sum !== FOCUS_TOTAL) {
|
|
||||||
return "Your five focus numbers total " + sum + ". They must total exactly " +
|
|
||||||
FOCUS_TOTAL + ".";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wire one form's sliders: five <input type=range> with an adjacent <output>, a
|
/* Wire one form's sliders: five <input type=range> with an adjacent <output>, a
|
||||||
live running total, and a live warning while the number is wrong. */
|
live running total, and a live warning while the number is wrong. */
|
||||||
function initFocusUI(form, warnId, totalId) {
|
function initFocusUI(form, warnId, totalId) {
|
||||||
if (!form) return;
|
if (!form) return;
|
||||||
|
// The legend text comes from the shared rule (static/focus-rule.js), not the markup.
|
||||||
|
var legendEl = form.querySelector(".focus-field legend");
|
||||||
|
if (legendEl) legendEl.textContent = O4PFocus.LEGEND;
|
||||||
var wraps = form.querySelectorAll(".focus-field");
|
var wraps = form.querySelectorAll(".focus-field");
|
||||||
Array.prototype.forEach.call(wraps, function (w) {
|
Array.prototype.forEach.call(wraps, function (w) {
|
||||||
var hidden = w.querySelector(".focus-sliders");
|
var hidden = w.querySelector(".focus-sliders");
|
||||||
@@ -2125,12 +2121,7 @@
|
|||||||
el.setAttribute("aria-valuetext", n + " of " + FOCUS_MAX);
|
el.setAttribute("aria-valuetext", n + " of " + FOCUS_MAX);
|
||||||
});
|
});
|
||||||
if (total) total.textContent = sum + " of " + FOCUS_TOTAL + " points";
|
if (total) total.textContent = sum + " of " + FOCUS_TOTAL + " points";
|
||||||
if (warn) {
|
if (warn) warn.textContent = O4PFocus.message(sum);
|
||||||
warn.textContent = sum === FOCUS_TOTAL
|
|
||||||
? ""
|
|
||||||
: (sum === 0 ? "You have 0 of 15 — place all 15 points."
|
|
||||||
: "You have " + sum + " of 15. The five must total exactly 15.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Array.prototype.forEach.call(form.querySelectorAll(".focus-field input"), function (el) {
|
Array.prototype.forEach.call(form.querySelectorAll(".focus-field input"), function (el) {
|
||||||
el.addEventListener("input", refresh);
|
el.addEventListener("input", refresh);
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/* The ONE source of truth for the "skill profile" rule — the 15-point budget.
|
||||||
|
Two forms render this rule: the directory application form
|
||||||
|
(/odoo-community-developers/) and the private self-service edit form
|
||||||
|
(/freelancer-edit/). Both take the legend, the directive and the wrong-total
|
||||||
|
message from here, so the two cannot word the same rule differently again.
|
||||||
|
Loaded before each page's own script. */
|
||||||
|
(function () {
|
||||||
|
var TOTAL = 15;
|
||||||
|
window.O4PFocus = {
|
||||||
|
TOTAL: TOTAL,
|
||||||
|
MAX: 5,
|
||||||
|
LEGEND: "Skill profile — 15 points to distribute",
|
||||||
|
DIRECTIVE: "Distribute all 15 points across the five areas — they cannot all be 0.",
|
||||||
|
/* The wrong-total message, naming the direction to move. "" when the sum is right. */
|
||||||
|
message: function (sum) {
|
||||||
|
if (sum === TOTAL) return "";
|
||||||
|
if (sum === 0) return "You have 0 of " + TOTAL + " — place all " + TOTAL + " points.";
|
||||||
|
if (sum > TOTAL) return "You have " + sum + " of " + TOTAL + " — remove " + (sum - TOTAL) + ".";
|
||||||
|
return "You have " + sum + " of " + TOTAL + " — add " + (TOTAL - sum) + ".";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
Reference in new issue
Block a user