Skip to main content
iVentureTeam

project_state_selection

The green, orange and red status bubble on an Odoo project is project_state_selection. It swaps the generic state colors for the five-color project palette, and quietly removes one status from the dropdown.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 26, 2026Updated August 26, 20265 min read
Technical nameproject_state_selection
Field typesselection
Viewslist, kanban
Also registered askanban.project_state_selection (16 only)
Moduleproject
Used in core2 occurrences across 1 module: the project list and kanban views in project
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. Applied in XML; Studio does not list it
Alternativesstate_selection, status_with_color, project_task_state_selection

What the Project status widget does

Project managers rate a project's health with the status field last_update_status: On Track, At Risk, Off Track, On Hold, Done, plus a To Define default for new projects. This widget renders that selection as a colored bubble with a dropdown, in the project list's Status column and on kanban cards.

It subclasses the generic state_selection widget and changes two things. First, the colors: instead of the generic red and green pair it installs the project palette, a value-to-number map documented in project_update.py, and switches the CSS prefix so each status renders as o_status_bubble o_color_bubble_<n>. On Track is 20, On Hold 21, At Risk 22, Off Track 23, Done 24.

Second, the choices: its options getter filters the value to_define out of the dropdown. A freshly created project displays the neutral bubble of its default To Define status, but the moment someone picks a real status there is no way back from the widget.

What this means for your team

The status bubble is the fastest portfolio signal in Odoo. A director scanning forty projects reads the color column in seconds; the same field feeds project updates, where each recorded update snapshots the status at that date.

The removed To Define option is a small piece of product opinion worth copying: undefined is an acceptable starting point but not an acceptable answer. Once a manager has rated the project, the UI refuses to let them un-rate it, which keeps portfolio reports free of projects that drifted back to unknown.

Because the bubble writes last_update_status directly with an immediate save, it also pairs naturally with automations: a status flip to Off Track can trigger an activity for the program lead or a message to a steering channel, and the change is stamped the moment it is clicked.

Supported options in Odoo 19

The widget declares no options of its own. Since Odoo 17 it spreads the generic stateSelectionField descriptor, so the two inherited options below apply, both verified in the Odoo 19.0 source. In Odoo 16 the descriptor did not exist and no options were extracted at all.

OptionTypeWhat it does
autosavebooleanInherited from state_selection since 17. Picking a status saves the whole record immediately, pending edits included, unless you pass {'autosave': False}. In 16 the option was never read because the widget registered without a descriptor.(default: true)(since Odoo 17.0)
hide_labelbooleanInherited from state_selection since 17. The label only renders when you explicitly pass {'hide_label': False}; by default the widget is a bare colored bubble, which is how core uses it in the 20px list column.(default: true (label hidden))(since Odoo 17.0)

The bubble hides its label by default. The inherited extractProps shows the status text only when you pass {'hide_label': False}. Core's list view instead titles the column Status and keeps the cell as a bare 20px bubble via nolabel and a width hint.

Working examples

How core applies it in the project list

<field name="last_update_color" column_invisible="True"/>
<field name="last_update_status" string="Status" nolabel="1" width="20px"
       widget="project_state_selection" invisible="is_template"/>

Showing the status text next to the bubble

<field name="last_update_status" widget="project_state_selection"
       options="{'hide_label': False}"/>

Read-only display trick used by core kanban

For non-editable kanban cards, core skips the widget entirely and renders the stored color number as a static bubble:

<span t-att-class="'o_status_bubble mx-0 o_color_bubble_' + record.last_update_color.value"/>

That works because the model stores the same palette number in last_update_color that the widget derives from the status value.

Registration history and the shared palette

The 16-to-17 registration change is the detail that bites during migrations.

In Odoo 16 the bare name did not exist. The file registered only kanban.project_state_selection, a view-prefixed entry, and registered the raw component class rather than a descriptor. Two consequences: the widget worked only in kanban views, and because there was no descriptor there was no extractProps, so options like autosave were never read. A 16 view that wrote widget="project_state_selection" in a list or form logged Missing widget and fell back to the plain selection field.

Since 17 it is a normal descriptor under the bare name, usable in any view type, with the generic options flowing through. The 16 kanban-only registration was dropped in the same change.

The color plumbing is shared, not duplicated. The palette map and the o_status_bubble mx-0 o_color_bubble_ prefix are imported from project_utils.js, and the exact same constants power the status_with_color widget used on project updates. Change one and both change.

One dropped state, client-side only. The to_define filter lives in the widget's options getter, so server code and imports can still write the value; only the dropdown hides it. The current value always renders, whatever it is, because the button part shows the field's actual state.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. File byte-identical on the development branch; see below.
Odoo 19.0VerifiedVerified against the shipped source; adds only a small disabled-button style file.
Odoo 18.0VerifiedSame source. No XML changes needed.
Odoo 17.0VerifiedBare-name registration and descriptor introduced; options work from here.
Odoo 16.0Partial / changedRegistered only as kanban.project_state_selection, class-only; unusable outside kanban and options ignored.

Upgrade note. Views written for 17, 18 or 19 carry over untouched. Views coming from 16 need review: outside kanban the widget name silently did nothing there, so a migrated list view may start showing bubbles where it previously showed a plain selection.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026, and the development branch can change until release.

As of this writing the widget file is byte-identical between 19.0 and the development branch: same palette, same To Define filter, same registration. The relevant movement is upstream again: the parent state_selection widget loses its autosave option on the branch, which would make the immediate-save behavior this subclass inherits unconditional rather than configurable. We re-verify after release.

Common problems and fixes

SymptomCause and fix
To Define is missing from the dropdownThe widget's options getter filters the to_define value out on purpose. Working as designed; set the value from server code or an import if you truly need to reset it.
In Odoo 16 the widget does nothing in list or form views16 registered it only under the kanban. prefix, so other views fell back to the plain selection. Upgrade to 17+ where the bare name exists, or accept kanban-only behavior on 16.
Status bubble has no color for a custom selection valueThe palette maps only on_track, at_risk, off_track, on_hold and done to bubble numbers. Extend STATUS_COLORS in a JS patch if you add custom statuses; unknown values render the neutral bubble.
Clicking a status saves the record before other edits are doneInherited autosave defaults to true and saves the entire record. Pass options="{'autosave': False}" where the status change should stay pending.
Kanban card shows a bubble that is not clickableCore renders a static span with last_update_color when the kanban is not editable. Expected; the live widget only appears for editable cards with a status set.

Project status widget vs the alternatives

WidgetBest forKey difference
project_state_selectionThe five-status health rating on project.project in lists and kanbansProject color palette on numbered bubbles, with To Define removed from the dropdown
state_selectionGeneric three-state kanban_state flags on any modelRed and green only, keeps every selection value in its dropdown
status_with_colorShowing a recorded project update's statusSame palette but attribute-driven and display-oriented, with its own hide options
project_task_state_selectionTask-level states with approval and canceled valuesDifferent vocabulary and icon set, aimed at tasks rather than project health

On project.project itself, this widget is the only one that speaks the five-status palette. Reach for the generic state_selection on other models, and for status_with_color when displaying a recorded project update's status rather than the live project field.

Frequently asked questions

What is the project_state_selection widget in Odoo?+
It is the project module's version of the state bullet: it renders last_update_status on projects as a colored bubble with a dropdown, using the five-color project palette instead of the generic red and green.
Why can't I set a project back to To Define?+
The widget deliberately filters to_define out of its dropdown. New projects start there by default, but once rated, the UI only offers the five real statuses. Server-side writes can still set it.
Which colors map to which project status?+
On Track is bubble color 20 (green), On Hold 21, At Risk 22 (orange), Off Track 23 (red), Done 24. The same numbers are stored in the last_update_color field on the project.
Can I use project_state_selection on my own model?+
Yes, if your selection uses the same value keys; the colors are keyed on on_track, at_risk, off_track, on_hold and done. Different keys render neutral bubbles, so for custom vocabularies patch STATUS_COLORS or subclass state_selection yourself.
Why did the widget not work in my Odoo 16 list view?+
In 16 it was registered only as kanban.project_state_selection, so list and form views logged Missing widget and fell back to a plain selection. The bare-name registration arrived in Odoo 17.

Project statuses your steering meetings can trust?

We implement Odoo project portfolios with health statuses wired to updates, automated escalation when a project goes Off Track, and list views your PMO reads in one glance, across Odoo 16 to 19.

Plan your project setup

How this page was produced

This page was verified by reading project_state_selection.js and project_utils.js in the Odoo 19.0 project module, the base state_selection_field.js in web, and the core usages in project_project_views.xml, plus the 16.0 file for the registration history. The Odoo 20 section is a diff against the public development branch. Found a discrepancy? Report it and we will correct the page.