|
|
|
merged
[FIX] viin_backend_theme: keep apps menu open while app reloads
|
[FIX] viin_backend_theme: keep apps menu open while app reloads
Opening the apps menu from the navbar while an app was still reloading
(for example clicking the app brand and then the apps button before the
screen finished loading) closed the menu before its tiles appeared, so
the user saw nothing to pick an app from. It broke the runbot
hr_expense tour create_expense_no_employee_access_tour (step 13/13,
.o_app tile not found, 4 failures out of 5 runs).
Cause: NavBar.setup() closed the menu overlay on every
ACTION_MANAGER:UI-UPDATED. The reload started by the brand click
finished while the overlay's ViinHomeMenu was still in onWillStart (its
mail.activity search_count and res.users read RPCs), so the overlay
entry was removed before any tile was mounted.
The UI-UPDATED listener is removed. The menu is still closed by a route
change, outside click, Escape and when the navbar is destroyed; the
mobile "All Apps" guard that refuses to open a menu before any screen
exists is unchanged.
Tests: a Hoot desktop test holds the list reload and the menu's own
RPCs and requires the overlay and its app tiles to be on screen once
both finish; it fails with the listener and passes without it. The
mobile test that faked a screen to assert the removed close is dropped;
the real guard stays covered by "All Apps tapped while the boot app menu
is still loading opens no overlay and the toggle keeps working".
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[FWD] 18.0 -> 19.0: de-brand POS/Inventory/Manufacturing, mobile apps menu
|
[FIX] viin_brand_mrp: neutral operation cost help
The "Cost based on" help of BoM operations no longer names Odoo,
in English or Vietnamese.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[FWD] 18.0 -> 19.0: de-brand POS/Inventory/Manufacturing, mobile apps menu
|
[FIX] viin_brand_mrp: neutral operation cost help
The "Cost based on" help of BoM operations no longer names Odoo,
in English or Vietnamese.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[I18N] *: align Vietnamese terminology with the corrected core catalogs
|
[I18N] *: align Vietnamese terminology with the corrected core catalogs
Odoo 19 core's Vietnamese catalogs were corrected against the glossary
researched per business domain (Viindoo/odoo#1302). This brings this
repository's catalogs in line, so a Vietnamese user sees one term for
one concept across core and Viindoo modules. The 18.0 alignment came
over with the forward-port; this covers the strings new in 19.0 and
the terms decided for 19.0:
- Records shared with core (model names, re-declared fields, selection
values) now carry core's 19.0 wording exactly; before, the module
loaded last decided which label users saw.
- 19.0 terms: weekdays in word form (Thứ Hai ... Chủ Nhật).
- The approved glossary applied in context to strings new in 19.0
(Phiếu kho, Loại nghiệp vụ, Cổng thanh toán, Đóng kiện, ...), and
debranded help texts say "hệ thống" where the source does, not
"Odoo".
- Definite errors fixed: reversed or wrong meanings, broken
placeholders and markup, English left in translations, garbled text
and typos.
- Old-style tone marks throughout (hóa, hủy, khóa), ASCII hyphens.
Only msgstr content changes; untranslated entries are left as they are.
|
Failed
|
|
|
|
|
|
|
|
merged
Fwd from 18 to 19 261009 01
|
Merge remote-tracking branch 'origin/18.0' into 19.0
Range 4a5885d (1 commit). Conflict resolution:
- i18n/vi_VN.po: kept the 19.0 catalog shape and entries; where 18.0
changed a msgstr and the same msgid exists on 19.0, the 18.0 wording
wins.
- viin_brand_common (renamed viin_brand_base_setup on 19.0): its 18.0
msgstr change applied to viin_brand_base_setup/i18n/vi_VN.po.
- viin_brand_membership (removed on 19.0): catalog stays deleted.
|
Failed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_web: scope the navbar hover/active hook guard to the regular navbar
|
[FIX] viin_brand_web: scope the navbar hover/active hook guard to the regular navbar
test_navbar_menu_entry_interactive_states_use_deep_chrome_rung asserted
that core never DECLARES --NavBar-entry-backgroundColor--hover/--active,
because the var() fallback those hooks read is what carries the brand's
deep chrome rung. It checked that with a substring scan over the whole
compiled web.assets_backend, so any declaration anywhere tripped it.
viin_customizer declares both hooks to theme its own dark top bar:
`.customizer_container .customizer_navbar .o_main_navbar { ... }`. That
rule never applies to the regular web client navbar, so the brand rung
there is untouched, yet the scan reported it as core re-declaring the
hook and the test went red as soon as viin_customizer was installed.
The guard now collects only the declarations whose selector can reach
the regular navbar entries - the entry itself or any ancestor on the
NAVBAR_ANCESTORS chain, including class-less subjects such as :root.
Custom properties inherit, so an ancestor-level declaration counts; a
declaration under a context the navbar is not in does not. The check
cannot be left to the cascade resolution further down: that walks only
the entry, so a `.o_main_navbar` declaration inherited from above would
stay invisible to it.
Verified on 19.0 with viin_brand_web and viin_customizer installed:
the old guard fails with "'--NavBar-entry-backgroundColor--hover:'
unexpectedly found", the new one passes, and temporarily adding
`.o_main_navbar { --NavBar-entry-backgroundColor--hover: #00bbce }` to
the brand bundle still makes it fail.
Also reword the docstring of viin_backend_theme's
test_navbar_apps_icon_computes_cores_navbar_entry_colour. It said nothing
in the addons path declares --NavBar-entry-color, which stops being true
once viin_customizer is installed. It now says no rule that reaches the
regular navbar declares it, and that viin_customizer's declaration lives
only under its own .customizer_navbar scope, which the cascade resolver
excludes. Docstring only; that test class still passes with
viin_customizer installed.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_web: scope the navbar hover/active hook guard to the regular navbar
|
[FIX] viin_brand_web: scope the navbar hover/active hook guard to the regular navbar
test_navbar_menu_entry_interactive_states_use_deep_chrome_rung asserted
that core never DECLARES --NavBar-entry-backgroundColor--hover/--active,
because the var() fallback those hooks read is what carries the brand's
deep chrome rung. It checked that with a substring scan over the whole
compiled web.assets_backend, so any declaration anywhere tripped it.
viin_customizer declares both hooks to theme its own dark top bar:
`.customizer_container .customizer_navbar .o_main_navbar { ... }`. That
rule never applies to the regular web client navbar, so the brand rung
there is untouched, yet the scan reported it as core re-declaring the
hook and the test went red as soon as viin_customizer was installed.
The guard now collects only the declarations whose selector can reach
the regular navbar entries - the entry itself or any ancestor on the
NAVBAR_ANCESTORS chain, including class-less subjects such as :root.
Custom properties inherit, so an ancestor-level declaration counts; a
declaration under a context the navbar is not in does not. The check
cannot be left to the cascade resolution further down: that walks only
the entry, so a `.o_main_navbar` declaration inherited from above would
stay invisible to it.
Verified on 19.0 with viin_brand_web and viin_customizer installed:
the old guard fails with "'--NavBar-entry-backgroundColor--hover:'
unexpectedly found", the new one passes, and temporarily adding
`.o_main_navbar { --NavBar-entry-backgroundColor--hover: #00bbce }` to
the brand bundle still makes it fail.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_pos: Fix branding issues in customer facing display
|
[FIX] viin_brand_pos: Fix branding issues in customer facing display
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_website, viin_backend_theme: one click into the backend, and type to search
|
[IMP] viin_brand_website: one click from the site into the backend
Clicking the apps grid on the website used to open a dropdown listing the
internal user's apps, so reaching the backend cost an extra click every time.
The button now links straight to /odoo and no longer toggles anything.
/odoo can take a noticeable moment on an install with many modules, so the icon
swaps to a spinner on click: the user can see the click registered. A
Ctrl/Cmd/Shift or middle click opens the backend in a new tab and leaves the
current page's icon alone, and a Back-button restore from the browser's cache
puts the icon back rather than leaving it spinning for good.
That spinner is wired by a delegated listener on the document, not by a public
Interaction. It was written as an Interaction first and it never ran: the
interaction service scans from #wrapwrap, and this button renders outside it,
under body > .o_frontend_to_backend_nav > .o_frontend_to_backend_buttons. Core
drives this same bar from a plain frontend module for the same reason. Both
click and auxclick are bound, because a non-primary click fires the latter and
core treats the two as a pair.
The spinner is a dedicated child element rather than classes on the anchor,
and that distinction is the whole of the difference. Core renders that anchor
as both the icon and a styled flex box, so a spin class on it rotates the box
- background, padding and all - which is what it did at first. Every pending
indicator in Odoo 19 puts fa fa-circle-o-notch fa-spin on an element whose
only job is to be the spinner, and this now does the same. Measured with the
animation frozen at one angle: the old anchor's bounding box grew from 48x54
to 72x72 as the box turned; the anchor now holds 48x54, identical to an
untouched button, and only the glyph inside it moves. The tour asserts the
anchor carries no spin class, so putting one back there fails loudly instead
of passing.
Core's own dropdown markup beside the button is left exactly as core renders
it, including the ir.ui.menu lookup it performs on every frontend page. Taking
it out looked like a free win and was tried twice; core's
website_backend_menus_redirect tour opens that dropdown and clicks an entry
inside it, and the entry only exists when the lookup runs.
The de-branded title on the button is unchanged.
Tests: the click, modifier and cache-restore behaviour are covered on a real
DOM rather than by matching the text of an inline handler, which an
implementation with the transitions swapped passed just as happily. A tour
drives the button on a real rendered page and asserts both that the icon swaps
and that the button is NOT inside #wrapwrap, so if a future Odoo moves it the
guard fails loudly instead of passing for the wrong reason - a unit test cannot
make that assertion, because the test helper fabricates a #wrapwrap of its own,
which is precisely why nine green unit tests hid a feature that did not work.
Bundle guards assert the module really reaches the browser.
Also here, and separable from the behaviour: comments in this module's tests
cited source by line number. Each now names the symbol instead. One had already
rotted badly, naming a method while pointing fifteen lines above its real
definition.
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_website, viin_backend_theme: one click into the backend, and type to search
|
[IMP] viin_brand_website: one click from the site into the backend
Clicking the apps grid on the website used to open a dropdown listing the
internal user's apps, so reaching the backend cost an extra click every time.
The button now links straight to /odoo and no longer toggles anything.
/odoo can take a noticeable moment on an install with many modules, so the icon
swaps to a spinner on click: the user can see the click registered. A
Ctrl/Cmd/Shift or middle click opens the backend in a new tab and leaves the
current page's icon alone, and a Back-button restore from the browser's cache
puts the icon back rather than leaving it spinning for good.
That spinner is wired by a delegated listener on the document, not by a public
Interaction. It was written as an Interaction first and it never ran: the
interaction service scans from #wrapwrap, and this button renders outside it,
under body > .o_frontend_to_backend_nav > .o_frontend_to_backend_buttons. Core
drives this same bar from a plain frontend module for the same reason. Both
click and auxclick are bound, because a non-primary click fires the latter and
core treats the two as a pair.
Core's own dropdown markup beside the button is left exactly as core renders
it, including the ir.ui.menu lookup it performs on every frontend page. Taking
it out looked like a free win and was tried twice; core's
website_backend_menus_redirect tour opens that dropdown and clicks an entry
inside it, and the entry only exists when the lookup runs.
The de-branded title on the button is unchanged.
Tests: the click, modifier and cache-restore behaviour are covered on a real
DOM rather than by matching the text of an inline handler, which an
implementation with the transitions swapped passed just as happily. A tour
drives the button on a real rendered page and asserts both that the icon swaps
and that the button is NOT inside #wrapwrap, so if a future Odoo moves it the
guard fails loudly instead of passing for the wrong reason - a unit test cannot
make that assertion, because the test helper fabricates a #wrapwrap of its own,
which is precisely why nine green unit tests hid a feature that did not work.
Bundle guards assert the module really reaches the browser.
Also here, and separable from the behaviour: comments in this module's tests
cited source by line number. Each now names the symbol instead. One had already
rotted badly, naming a method while pointing fifteen lines above its real
definition.
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_website, viin_backend_theme: one click into the backend, and type to search
|
[FIX] viin_brand_website: wire the apps button off the DOM it is in
The apps-button spinner never ran on a real page. It was written as a
public Interaction, and the interaction service only ever scans from
#wrapwrap, but the button sits outside it - it is a
`body > .o_frontend_to_backend_nav > .o_frontend_to_backend_buttons >
a`, a #wrapwrap SIBLING, never a descendant. So the interaction never
started, the icon never swapped on click, and a Back-button restore
never reset it.
Replace it with a delegated click/auxclick listener bound on the
document at load time, which does not care where the button lives.
The three functions that decide what happens on click are unchanged.
The nine unit tests over the old Interaction had all been passing for
the wrong reason: the Hoot fixture helper wraps bare markup in a
#wrapwrap of its own, so the suite was exercising the button in a
position it never occupies on the real page. Those tests now mount
the fixture directly against the new listener, and a tour drives the
real rendered homepage - asserting both that the click swaps the icon
and that the button is NOT inside #wrapwrap, so a future core move
that reintroduces the mismatch fails loudly instead of passing for
the wrong reason again.
|
Failed
|
|
|
|
|
|
|
|
open
[REF] viin_brand cluster: make each module installable alone
|
[MISC] viin_brand_spreadsheet_dashboard: guard tours on web_tour
Tests that boot the webclient via start_tour required the tour engine
unconditionally, so they errored instead of skipping under the
acceptance CLI's --skip-auto-install flag, which excludes the
web_tour/bus auto-install closure. They now probe res.users for the
tour_enabled field in setUp and skip cleanly with a stated reason when
web_tour is not installed, so a per-module acceptance run stays
readable instead of burying a genuine failure under environment-driven
errors.
A bundle-compile test is added, compiling this module's real asset
bundles and asserting on the compiled output.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
open
[REF] viin_brand cluster: make each module installable alone
|
[MISC] pyproject: pin the repo's first ruff lint configuration
Ruff was running fully unconfigured against this repository. A
repo-root pyproject.toml now establishes an explicit configuration,
pinning today's implicit rule set so a future ruff upgrade cannot
silently change what is enforced.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_web: resolve dark mode from the user, not the browser
|
[FIX] viin_brand_web: resolve dark mode from the user, not the browser
Two reported symptoms, one root cause: the code treated the
`color_scheme` cookie as if it were a preference, when it is a cache of
a resolution. A preference belongs to a USER; this cookie belongs to a
BROWSER and outlives the session that wrote it.
Symptom 1 - another person's cookie decided your scheme. color_scheme()
ranked the cookie above the stored preference, so on a shared browser
the last user's choice served the next user the wrong compiled bundle.
Measured before the change: preference 'light' plus a
`color_scheme=dark` cookie rendered data-bs-theme="dark", with the dark
bundle referenced.
Symptom 2 - "System" always came up light. setScheme('auto') writes the
matchMedia-resolved scheme to the cookie, then awaits an ORM write whose
own handler expired that very cookie. Measured: the write response
carried `color_scheme=; Max-Age=0; Path=/`, the host-only cookie left
the jar, and the reload that follows then found no cookie, fell through
to core's `return "light"`, and served light whatever the device said.
The client re-resolved afterwards, so the user saw light, a half-flip,
and dark only on the next reload.
The resolution order is now the user's own explicit light/dark
preference, then the cookie, then super(). The cookie keeps its place
above super() because 'auto' is the one case the server genuinely cannot
decide: it cannot read the device preference, so the client resolves it
and caches the effective light|dark there. For the same reason writing
'auto' no longer expires the cookie - that would throw away the only
copy of the answer the imminent reload needs.
That cookie is also core's own client-side source of truth for dark
mode: core reads it for graph colours, the colour picker, the ace editor
and the pdf.js viewer. Expiring it did not merely mis-pick a bundle, it
left every one of those drawing light-mode colours inside a dark UI.
Two tests pinned the old behaviour and are replaced, not loosened. One
asserted the cookie "overrides everything"; it now asserts an explicit
preference survives a contrary cookie, with a sibling covering the
'auto' case where the cookie is authoritative. The other asserted the
switch to 'auto' expires the cookie, citing the old precedence as its
reason; it now asserts the cached resolution is left alone. Both were
protecting a defect, so changing them is a corrected contract, not an
expectation bent to match output.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
open
[REF] viin_brand cluster: make each module installable alone
|
[MISC] pyproject: pin the repo's first ruff lint configuration
Ruff was running fully unconfigured against this repository. A
repo-root pyproject.toml now establishes an explicit configuration,
pinning today's implicit rule set so a future ruff upgrade cannot
silently change what is enforced.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[FIX] dark mode: readable pivot/graph, dark spreadsheet and dashboard chrome, calmer Discuss seams
|
[FIX] viin_backend_theme: dedupe the active marker in the Appearance menu
The Appearance systray menu's active Theme row and active Density row each
drew two selected-markers: core's own `.dropdown-item.active::before`
FontAwesome checkmark painted on top of this component's own right-aligned
check icon, so the active choice showed a double mark instead of one.
Core's marker is suppressed on both DropdownItem loops with core's own
opt-out class `dropdown-item_active_noarrow`, leaving the component's own
check as the single indicator. mail's action list already reuses that class
for the identical situation, so this reuses an existing core lever instead
of inventing new CSS.
A tour-driven HttpCase asserts the rendered result - the active row's
computed `::before` is 'none' and exactly one visible `.fa-check` remains
inside it - in both the light and the dark colour scheme, so the contract
is pinned on render output rather than on markup.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] dark mode: readable pivot/graph, dark spreadsheet and dashboard chrome, calmer Discuss seams
|
[FIX] viin_backend_theme: dedupe active marker in Appearance menu
The Appearance systray menu's active Theme row and active Density row
each drew two selected-markers: core's own
`.dropdown-item.active::before` FontAwesome checkmark painted on top
of this component's own right-aligned check icon, so the active
choice showed a double mark instead of one.
Suppressed core's marker on both DropdownItem loops with core's own
opt-out class `dropdown-item_active_noarrow`, keeping the component's
own check as the single indicator. mail's action list already reuses
this same class for the identical situation, so this reuses an
existing core lever instead of inventing new CSS.
Added a tour-driven HttpCase asserting the rendered result - the
active row's computed `::before` is 'none' and exactly one visible
`.fa-check` remains inside it - in both light and dark colour scheme,
so the contract is pinned on render output rather than on markup.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
Fwd from 18 to 19 20260912 01
|
Merge remote-tracking branch 'Viindoo/18.0' into 19.0
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_mail: fix chatter contrast in light and dark schemes
|
[FIX] viin_brand_mail: fix chatter contrast, harden dark edited marker
DARK: the mail chatter embedded in the Odoo 19 spreadsheet editor's
comments side panel was unreadable. Odoo keeps the spreadsheet a light
island inside a dark app (its dark-bundle-only
o_spreadsheet_extended.dark.scss forces .bg-white back to white and
pins .btn to a dark label), but core repaints only the button label,
not the fill, leaving half of every pair in the wrong colour scheme.
Finish that light island for the embedded chatter instead of darkening
it, scoped entirely under .o-spreadsheet. Measured live at 1440px in
dark mode, before -> after: Log note 1.19 -> 7.92, Activity
1.19 -> 7.92, Send message 2.17 -> 8.24, author name 2.63 -> 10.31,
timestamp 2.59 -> 6.11, message body -> 9.25.
The same two message nodes the island fix above touches - the
empty-message placeholder (3.37:1 worst) and the (edited) marker
(4.04:1 worst) - were unreadable everywhere OUTSIDE that island too,
because core dims both a second time on top of a tier already tuned to
clear AA once. Fix them product-wide instead of leaving the island as
the one readable spot: every form-view chatter, the Discuss thread
canvas and every chat window, on the panel and on all three
message-bubble tints. With that rule in place the island's own
placeholder correction became a pure duplicate of it and was dropped.
The island's (edited) rule is kept and hardened with its own colour,
because the product-wide fix lands that marker on the dark metadata
tier, which measures 2.34-2.59:1 on the island's light bubbles - too
dark for that ground.
LIGHT: the mail message muted tier renders below AA wherever it lands
- 4.06:1 on a message bubble, 4.20:1 on the chatter panel - and two
nodes are dimmed further by opacity utilities to 2.7:1 and 2.4:1. The
shared $text-muted token is deliberately left untouched: it also paints
off/disabled affordances that WCAG exempts, and repointing it would
change roughly 380 nodes across 205 templates. Re-point the tier for
mail message surfaces only. After: 5.48-6.11 across the panel and all
bubble variants. Dark stays provably unaffected, since the light rules
compile to zero bytes in the dark bundle.
Also drop a rule that went dead once the comments panel lost its
background utility - it was this module's only reference to another
repo's class.
A comment on the read-conversation muted tier said its
--secondary-color token "does not flip" in dark - true only while
$o-main-color-muted and $body-secondary-color were two independent
Sass values. dark_palette.scss has since aliased the former onto the
latter, so both names now resolve to the one tier this rule already
reads: the rule was right, the explanation had gone stale. Reworded to
name the tier through its own alias chain instead of restating a
divergence that no longer exists.
Guard every case above with tests that assert computed WCAG ratios,
never colour values.
DARK EDITED MARKER, HARDENED: the product-wide dark rule just added
above (.o-mail-Message-edited .opacity-50 in mail_dark.scss) read the
bare Bootstrap Sass global $text-muted, which has no !default guard,
so any module sharing the web.assets_web_dark compile can reassign it
from under this one. Core's hr_skills does exactly that.
hr_skills/__manifest__.py:53 wildcard-globs
'hr_skills/static/src/scss/*.scss' into web.assets_backend, separately
from the intended web.report_assets_pdf entry on line 68; that glob
also catches report_employee_cv.scss, whose line 3 hard-assigns
$text-muted: #3b4757 with no !default; and the bundle chain
web.assets_web_dark -> web.assets_web -> web.assets_backend carries
that value in. So whenever hr_skills is installed alongside the
branding modules (always true on Runbot, which installs the whole
repo) the marker compiled to the wrong colour and failed WCAG AA
contrast (~1.3-2.0:1, needs >= 4.5:1).
A one-variable install-topology experiment proved it: same commit,
same suite - the three branding modules installed alone compiled
$text-muted to #8EA5A8 and passed all 147 tests; adding hr_skills to
the install set, nothing else changed, compiled it to #3b4757 and
failed 12 subtests. That asymmetry is exactly why the branch stayed
green on a local, branding-only run while Runbot - which always
installs the whole repo - was red on the same code.
Re-point the rule to var(--secondary-color) - the CSS custom property
Bootstrap emits from $body-secondary-color (a different Sass variable,
hard-assigned in dark_palette.scss:76 with no !default, which
hr_skills' write never touches) - matching an existing pattern already
used twice in this file (:56 and :245) for the analogous
chatter-timestamp / notification-item cases. Updated the neighbouring
comment to match, since it previously explained the value in terms of
$text-muted.
Added a regression guard,
test_dark_edited_marker_stays_readable_when_another_module_hijacks_text_muted,
that splices hr_skills' exact clobbering literal into the real
web.assets_web_dark bundle source and recompiles through Odoo's own
AssetsBundle.compile_css / ScssStylesheetAsset.compile (libsass),
proving the rule survives a hijacked $text-muted regardless of which
modules happen to be installed on whatever DB runs this module's own
suite (no cr.commit(), no real hr_skills install needed).
Verified RED before (12 genuine assertion failures on a live instance
with hr_skills installed) and GREEN after (0 failed, 0 errors across
187 tests in viin_backend_theme + viin_brand_web + viin_brand_mail,
same instance, hr_skills genuinely installed).
Also fixes a flake8 E303 (too many blank lines) left behind while
extending the compiled-CSS test suite above.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[FIX] viin_brand_mail: fix chatter contrast in light and dark schemes
|
[FIX] viin_brand_mail: fix chatter contrast in light and dark schemes
DARK: the mail chatter embedded in the Odoo 19 spreadsheet editor's
comments side panel was unreadable. Odoo keeps the spreadsheet a light
island inside a dark app (its dark-bundle-only
o_spreadsheet_extended.dark.scss forces .bg-white back to white and
pins .btn to a dark label), but core repaints only the button label,
not the fill, leaving half of every pair in the wrong colour scheme.
Finish that light island for the embedded chatter instead of darkening
it, scoped entirely under .o-spreadsheet. Measured live at 1440px in
dark mode, before -> after: Log note 1.19 -> 7.92, Activity
1.19 -> 7.92, Send message 2.17 -> 8.24, author name 2.63 -> 10.31,
timestamp 2.59 -> 6.11, message body -> 9.25.
The same two message nodes the island fix above touches - the
empty-message placeholder (3.37:1 worst) and the (edited) marker
(4.04:1 worst) - were unreadable everywhere OUTSIDE that island too,
because core dims both a second time on top of a tier already tuned to
clear AA once. Fix them product-wide instead of leaving the island as
the one readable spot: every form-view chatter, the Discuss thread
canvas and every chat window, on the panel and on all three
message-bubble tints. With that rule in place the island's own
placeholder correction became a pure duplicate of it and was dropped.
The island's (edited) rule is kept and hardened with its own colour,
because the product-wide fix lands that marker on the dark metadata
tier, which measures 2.34-2.59:1 on the island's light bubbles - too
dark for that ground.
LIGHT: the mail message muted tier renders below AA wherever it lands
- 4.06:1 on a message bubble, 4.20:1 on the chatter panel - and two
nodes are dimmed further by opacity utilities to 2.7:1 and 2.4:1. The
shared $text-muted token is deliberately left untouched: it also paints
off/disabled affordances that WCAG exempts, and repointing it would
change roughly 380 nodes across 205 templates. Re-point the tier for
mail message surfaces only. After: 5.48-6.11 across the panel and all
bubble variants. Dark stays provably unaffected, since the light rules
compile to zero bytes in the dark bundle.
Also drop a rule that went dead once the comments panel lost its
background utility - it was this module's only reference to another
repo's class.
A comment on the read-conversation muted tier said its
--secondary-color token "does not flip" in dark - true only while
$o-main-color-muted and $body-secondary-color were two independent
Sass values. dark_palette.scss has since aliased the former onto the
latter, so both names now resolve to the one tier this rule already
reads: the rule was right, the explanation had gone stale. Reworded to
name the tier through its own alias chain instead of restating a
divergence that no longer exists.
Guard every case above with tests that assert computed WCAG ratios,
never colour values.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|