|
|
|
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
|
|
|
|
|
|
|
|
merged
[FIX] viin_backend_theme, viin_brand_{web,mail,pos}: stop breaking core Odoo 19
|
[FIX] viin_backend_theme: restyle core without rewriting it
A theme may change how Odoo looks. This one had begun changing what Odoo
says, what it does, and how it describes itself to assistive technology -
and runbot batch 223955 was where that came due.
The theme case-transformed two surfaces it does not own: core's
command-palette category block and the list view's column headers. Rendered
text is what Odoo's own automated checks, tour assertions, screen readers
and a user's copy-paste all read back, so a purely cosmetic rule turned 102
core checks red at once ("Command#" read back as "COMMAND#"). Core already
presents the palette's category label in capitals itself, so ours added
nothing. It was also a defect users could see: the class it targeted is the
block holding every command row, not the label, so its muted colour, 11px
size, weight and letter-spacing were inherited by every row in the palette.
Aiming the rule at the label alone restores the rows to core's typography.
Odoo ends every font stack it ships with two safety nets: a small Noto
subset for characters a system font lacks or renders badly, and the four
emoji families. This theme replaced Odoo's stacks with its own and dropped
both nets from headings and from body text, so an emoji or an uncommon
script in ordinary backend text - a customer name, a chatter message, a
product label - could land on a system with nothing able to draw it and
render as an empty box. Both stacks are whole again and now end identically.
The brand heading font was also reaching into the rich-text editor, where an
outgoing email body inlines whatever font it is shown in, handing the
recipient a Viindoo face their mail client does not have and which is not
even vendored yet. Email bodies go back to the portable system stack; the
backend keeps Montserrat.
Clicking the navbar apps icon threw away whatever the user was working on.
The icon opened the home menu as a full page, so an open record, a half
filled form or a kanban the user had just filtered was torn down and had to
be rebuilt on the way back. Odoo's own contract for that icon is that it
shows the app list without navigating, and a large part of Odoo's test suite
is written on that assumption: 57 test files click it, some to pick an app,
others merely in passing before carrying on with the screen they were
already on. The latter could not work here at all, and the former could not
either, because our tiles were not the kind of element those tests look for.
The icon now shows the same full-screen home menu over the untouched view.
Pressing it again puts it away and the user is back where they were -
instantly, because nothing was ever destroyed - and so does clicking the
page behind it or pressing Escape, which the full-page version offered no
way to do. The design is unchanged: one icon, one home menu, and the landing
page shown at sign-in is untouched.
App tiles are now real links, as they are in stock Odoo, so they can be
opened in a new tab, copied, or announced sensibly. They had carried an
explicit role telling a screen reader each tile is an item in a list, never
that it is something the user can follow; because an explicit role replaces
an element's own rather than adding to it, the tiles were also absent from
links navigation, one of the main ways people using a screen reader move
through a page. That role is gone, and the grid's own list role went with
it, since a list is required to contain list items and keeping one alone
would have left an empty, malformed list rather than a fix. Wrapping each
tile to keep both was rejected: the tiles are laid out directly by the grid
and are the elements the drag-to-reorder handles, so a wrapper breaks the
layout and the reordering unless hidden by a CSS trick with its own record
of removing elements from the accessibility tree. Nothing on screen changes,
and keyboard navigation and drag-to-reorder are unaffected.
Guards now fail the build if this theme case-transforms anything it did not
author, if either font stack loses its fallback, or if a tile stops being
announced as a link; the font guard reads the value the browser is actually
handed rather than the source. One existing check was inverted rather than
weakened: it asserted the previous view was gone after clicking the apps
icon, which is the behaviour being fixed, and now asserts the view survives.
Owner decisions D1, D2 and D3, 2026-08-17.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
V19 fix imp viin brand cluster
|
[FIX] viin_backend_{web,theme}: remove redundant tests
|
Killed
|
|
|
|
|
|
|
|
merged
V19 fix imp viin brand cluster
|
[FIX] viin_backend_theme: remove redundant tests
|
Failed
|
|
|
|
|
|
|
|
merged
V19 fix imp viin brand cluster
|
[IMP] viin_brand_web: remove border-radius override and link override
|
Failed
|
|
|
|
|
|
|
|
merged
[REF] viin_brand_common: split into viin_brand_web + viin_brand_base_setup
|
[FIX] viin_brand_base_setup, viin_brand_web: split the catalogue to follow the artefacts
A stale #: reference silently DROPS the translation - the loader builds
ir_model_data keys straight out of the occurrence string, finds no row, and
skips the entry with no error and nothing red in any test suite.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[FWD] forward-port 18.0 -> 19.0 (0dafec5..467ac60, 9 commits)
|
[FIX] viin_brand_website: brand the websites a field default cannot reach
Removing the x_icon QWeb override was right - it resolved to website's own
producer and destroyed it, so a configured favicon could never be served. But
that override was also, incidentally, what made unconfigured websites look
branded: it forced the brand path at render time for every website regardless
of the stored field. With it gone the stored value renders, and for two
populations that value is still Odoo's icon - website.default_website, which
core creates while loading the website module, before this module's field
extension exists, and any website predating this module's install. A field
default fires only at record creation, so it reaches neither.
So on every existing 19.0 database this branch, as it stood, silently swapped
the Viindoo favicon for Odoo's. Reported by Codex on PR #664.
Corrected once, from two entry points that share one implementation:
post_init_hook for a fresh install, migrations/0.1.2 for a database where the
module is already installed. Both rewrite ONLY records byte-identical to core's
own default - those are provably nobody's choice - and leave every configured
favicon exactly as it is, which is the whole point of having removed the
override.
Verified on clean databases: a fresh install and an upgrade both end with the
default website branded, while a website whose owner set its own favicon keeps
it byte-for-byte. UntouchedFaviconsGetBrandedTest locks both halves - doing
nothing fails one assertion, overwriting everything fails the other.
|
Failed
|
|
|
|
|
|
|
|
merged
[FWD] forward-port 18.0 -> 19.0 (0dafec5..467ac60, 9 commits)
|
[FWD] forward-port 18.0 -> 19.0 (0dafec5..467ac60, 9 commits)
Absorbs every commit that landed on 18.0 since the last forward-port, so the
merge-base advances and none of them is reconsidered next run.
Three carry real behaviour to 19.0:
* viin_brand_website no longer replaces website.layout's x_icon producer. That
xpath resolved to core's own producer and destroyed it, so a customer who
configured their own favicon could never serve it. Branding now comes from a
field default in models/website.py: a new website starts branded, and the
customer's value wins the moment they set one. Locked by
tests/test_website_favicon_not_preempted.py.
* viin_backend_theme guards _loadDefaultApp before diverting to the home menu,
so an environment with a cleaned action registry falls back to the stock
default app instead of throwing during boot.
* viin_brand_website_sale drops the unverifiable "#1" ranking claim from the
eCommerce promo, in the template and both translation catalogs.
The rest are absorbed without adapt because 19.0 already moved past them:
web_responsive is gone entirely, replaced by viin_backend_theme; QUnit is
replaced by Hoot; the web.layout title/favicon fallback was deliberately
re-homed onto that template's callers and must not be restored.
One auto-merge carried a symbol that no longer exists here: the window-title
branding arrived guarded by session.viin_brand, a marker stamped by an
ir.http.session_info override 19.0 does not have, which would have left the
title permanently unbranded with no error. Reverted to the 19.0 version.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[19.0][UPG] viin_brand_*: upgrade to 19
|
[FIX] viin_backend_theme: realign radius invariant to owner decision D5
viin_brand_common's brand_variables.scss restores a pre-19 square-corners token
($o-border-radius: 0) in the previous commit; this file's cluster-wide "zero radius
overrides anywhere" invariant predates that restore and read it as the exact
regression it exists to catch. Owner decision D5 keeps the restore, so the guard is
updated to treat that single base-rung declaration as a pinned, SSOT-read exception
(-sm/-lg remain unchanged and must still equal core's own scale exactly) instead of a
violation.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[19.0][UPG] viin_brand_*: upgrade to 19
|
[UPG] viin_brand*: upgrade to version 19.0
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[REM] web_responsive: drop OCA responsive backend (superseded by viin_backend_theme's native mobile/rail redesign)
Was the legacy to_backend_theme's dependency; nothing else in the repo/tvtmaaddons/core depends on it.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[NEW] viin_backend_theme: Odoo 19 CE backend theme (Viindoo redesign), additive on the branding base
Purely-additive backend redesign on top of viin_brand_common + viin_brand_mail: instant OPT-IN dark
mode (native [data-bs-theme], per-user choice - public pages and the default state stay LIGHT), the
always-dark vertical rail + flat "Applications" home menu, form chrome + D6 statusbar->stepper,
list/kanban + bulk bar, split-screen login, overlays/skeleton/empty-states, mobile bottom-nav +
density toggle, appearance systray, Montserrat/Roboto typography. ZERO --viin-* custom properties;
native $o-* / Bootstrap levers + the cluster teal SSOT only; auto_install so the de-branded redesign
is the default on every Viindoo 19 DB.
Includes the W5 durable test layer (Hoot: theme service + D6 stepper; HttpCase tours: dark toggle,
home menu, density, mobile bottom-nav), the full dark-mode AA-contrast pass (form/dialog/grouped
list/kanban/pivot/calendar/search-panel/mail menus/chatter re-pointed to the runtime scheme props;
Bootstrap .text-* utilities relit in dark; light mode untouched), and the vi_VN translation.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Killed
|
|
Not finished
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[NEW] viin_backend_theme: Odoo 19 CE backend theme (Viindoo redesign), additive on the branding base
Purely-additive backend redesign on top of viin_brand_common + viin_brand_mail: instant OPT-IN dark
mode (native [data-bs-theme], per-user choice - public pages and the default state stay LIGHT), the
always-dark vertical rail + flat "Applications" home menu, form chrome + D6 statusbar->stepper,
list/kanban + bulk bar, split-screen login, overlays/skeleton/empty-states, mobile bottom-nav +
density toggle, appearance systray, Montserrat/Roboto typography. ZERO --viin-* custom properties;
native $o-* / Bootstrap levers + the cluster teal SSOT only; auto_install so the de-branded redesign
is the default on every Viindoo 19 DB.
Includes the W5 durable test layer (Hoot: theme service + D6 stepper; HttpCase tours: dark toggle,
home menu, density, mobile bottom-nav), the full dark-mode AA-contrast pass (form/dialog/grouped
list/kanban/pivot/calendar/search-panel/mail menus/chatter re-pointed to the runtime scheme props;
Bootstrap .text-* utilities relit in dark; light mode untouched), and the vi_VN translation.
Signed-off-by: David Tran <david.tran@tvtmarine.com>
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[FIX] viin_backend_theme: complete dark-mode AA coverage (opt-in, backend) + keep public login light
Dark mode is a LOGGED-IN per-user choice applied to the backend only; public pages and the
default state stay LIGHT. Two parts:
1. Public/default-light: remove login.scss's `@media (prefers-color-scheme: dark)` block - the
PUBLIC pre-auth login must not darken from the visitor's OS. The login now always renders the
light split-screen. Guard test_public_login_never_os_darkens bans re-adding it.
2. Complete the backend dark-mode AA coverage the earlier commit started, all dark-scoped
([data-bs-theme=dark]) so light mode is untouched. Odoo 19 CE core dark mode leaves many
surfaces on compiled light values that never scheme-flip; re-point them to the runtime scheme
props at the layer each is read:
- Backgrounds via the core CSS var (fixes the whole family at once): grouped-kanban
--Kanban-background/--KanbanGroup-background; form o2m list --ListRenderer-thead/tfoot-bg-color;
breadcrumb --breadcrumb-bg; a GLOBAL .bg-view --background-color flip (view-surface utility on
~14 surfaces incl. search panel + calendar container + inputs) - beats .bg-view's !important
WITHOUT an !important war since re-pointing its own local var; messaging systray
--mail-MessagingMenu-bg (core set it light in its OWN dark stylesheet); search-panel list-group.
- Text utilities compiled light + !important: .text-body/.text-muted/.text-900 relit WITH
!important (sparing .btn-light/.btn-secondary light chips); --body-color-rgb flipped for dark.
- Per-surface: search-panel active row (core hardcodes .text-black), field-selector chain part,
pivot cells/headers (beat core's o-hover-text-color mixin), chatter header, command-palette
footer, settings form (--settings__* vars + .settings bg + section titles).
- Calendar: re-point --fc-* tokens on the .fc element itself (FullCalendar declares them there,
so an ancestor rule loses) -> dark grid + readable day names/dates.
- .o_web_client color-scheme: correct core's invalid 'bright' ident to light/dark per the app
toggle (fixes native scrollbars/controls + the getComputedStyle skew).
REVERTED a mis-step from the prior iteration: a global .text-success/.text-info dark flip that,
being unscoped, lost contrast on light surfaces (selected rows/subtle alerts) - core's marginal
~3.7-3.9:1 values are accepted known-minors (like white-on-color badges), not regressed.
Live getComputedStyle-verified (the review browser runs force-dark, so screenshots are unreliable):
all primary daily screens (home/list/form/kanban/pivot/settings/dialog/dropdowns/command-palette/
search-panel/activities+messages menus/calendar/chatter) are AA-clean in dark, regression reverted,
0 console errors, light mode unchanged. ~24 source-invariant guards (TestReviewA11yFixes) protect
the intent; 52/52 theme tests green (Python /viin_backend_theme + Hoot bracket).
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[FIX] viin_backend_theme: dark-mode AA contrast (form, dialog, grouped list, kanban, text utilities)
A live acceptance review found several dark-mode surfaces still rendering
compiled light-mode colors that do not scheme-flip. Re-point them (dark-scoped,
so light mode is untouched) to the runtime scheme props, at the correct layer:
* Form: record title / headings -> var(--emphasis-color); field values/inputs
-> var(--body-color) (core .oe_title uses a compiled $headings-color hex).
* Light form labels: brand-purple leak -> neutral var(--secondary-color) (grey,
matches the mockup and the dark label tier).
* Teal FOREGROUND on dark (nocontent link, bulk-selection count, active notebook
tab, statusbar done glyph, many2one o_form_uri links): compiled #007F8E (3.69:1)
-> lighter dark teal #4FD4E2 (~9.9:1). Teal fills + the rail accent untouched.
* Dialog titles + any var-based heading: flip --heading-color -> var(--emphasis-color)
at the scheme engine (core $headings-color-dark is 'inherit', never flips).
* Grouped-list header + the Bootstrap .text-body/.text-muted utilities: these are
compiled with light values + !important into the dark bundle, so relit with
!important in dark (.text-muted spares .btn-light/.btn-secondary chips); also
fix the stale --body-color-rgb in the dark scheme.
* Overdue/rotting kanban card: core's static light-pink bg -> a dark-red color-mix
so its text is readable in dark (light mode keeps the pink).
* .o_web_client color-scheme: core's invalid 'bright' ($o-webclient-color-scheme)
-> light/dark per the app toggle, so native scrollbars/controls match the scheme.
All light-on-light / dark-on-light-chip cases verified non-regressed; light mode
unchanged. 13 source-invariant guards added (TestReviewA11yFixes). Live re-verify:
form/dialog/list/kanban/labels/links all clear AA in dark; 36/36 theme tests green.
|
Failed
|
|
|
|
|
|
|
|
merged
[UPG] branding-base cluster (5 modules) to Odoo 19.0 + de-brand/teal SSOT
|
[NEW] viin_backend_theme: W5 durable test layer (Hoot + HttpCase tours)
Adds the behavior-guard test layer for the theme, wired into web.assets_unit_tests
(Hoot) and web.assets_tests (tours), driven by tests/test_tours.py:
* Hoot - viin_theme service: setScheme dark/light flips documentElement data-bs-theme
+ persists the color_scheme cookie; setDensity compact flips data-viin-density +
viin_density cookie; 'auto' resolves via a mocked matchMedia and re-resolves on OS flip.
* Hoot - StatusBarField (D6) stepper: getStepInfo maps a mid-pipeline record to
done/current/upcoming markers; clicking a stage still fires core selectItem -> web_save
(presentation-only patch must not break click-to-change).
* HttpCase tours: instant dark toggle + reload persistence; density compact + reload
persistence (single-session location.reload, expectUnloadPage); home-menu fuzzy search
+ keyboard launch; mobile ViinBottomNav single-chrome + slot navigation (375x667 touch).
All assert observable state (RED-on-behavior-removal); no assertion is a code snapshot.
23/23 green on 19.0 CE (17 Python/tours + 6 Hoot).
|
Failed
|
|
|
|
|