Skip to content

docs: Document the model visualization contract (service-module + platform layers) - #2568

Open
oemebamo wants to merge 2 commits into
TimefoldAI:mainfrom
oemebamo:timefold-solver-enterprise-issues-815
Open

docs: Document the model visualization contract (service-module + platform layers)#2568
oemebamo wants to merge 2 commits into
TimefoldAI:mainfrom
oemebamo:timefold-solver-enterprise-issues-815

Conversation

@oemebamo

@oemebamo oemebamo commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Anything you only log to the console stays invisible to them.

[#_announcing_visualization_pages]
== Announcing visualization pages

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the first time I'm seeing this. Do you happen to know which model we use this for? Most model visualisations currently depend on a single page with multiple tabs.

@cedricdhooge96 cedricdhooge96 Aug 4, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answering my own question after digging in:

TL;DR: no model uses this, and nothing reads it either. Org-wide, timefold.model.visualization.pages appears only in the solver's own config class and test. On the platform side the field stops at the descriptor: ModelDescriptorDTO/RegisteredCatalogEntry never carry visualizationPages, and the frontend renders one hardcoded iframe gated only on uiSupport != "NONE". It shipped in #2510 to the shape the platform side requested (timefold-solver-enterprise#656), ahead of any consumer. The issue behind this PR (timefold-solver-enterprise#815) explicitly asked for that caveat to ship with this section ("say plainly it has no visible effect on the platform today"), but the section instead states the platform "knows what to offer users". Please add the caveat back.

How the pieces fit (the reason "single page with multiple tabs" is what we all see today): platform-drawn tabs need two things. First, knowing which pages exist, ideally before the iframe loads. That is this metadata: the menu card. Second, actually switching pages inside the iframe without reloading it, and knowing which page is active. That is a runtime postMessage channel (a views announce plus navigate), which already ships in the rebuilt FSR visualization but is not documented here: https://github.com/TimefoldAI/timefold-visualisations/blob/main/docs/EMBEDDING.md. Today the menu card is printed but nobody reads it, and the waiter works but is not on this page. Every existing model therefore still draws its own tabs inside the frame.

One more concrete fix for this page: the example icon TbChartGantt does not exist in react-icons 5.7.0, the version the platform frontend pins, so the doc's own example would render no icon once consumption lands (measured against the package; TbMap is fine). Worth picking an icon that resolves, and the "any icon name from Tabler Icons" sentence oversells slightly.

We are wiring the two halves together rather than keeping two systems, and this metadata wins the argument: the embed no longer declares its views at all (TimefoldAI/timefold-visualisations#87 removed the upward views message), so this build-time declaration is the single source of the tab set, and the runtime channel carries only what a running embed can know — readiness, the active view, and navigation. Consumption is tracked in TimefoldAI/timefold-platform#5274 (models API) and TimefoldAI/frontend#3991 (run-page menu), and the model-side declarations in TimefoldAI/timefold-field-service-routing#1385 / TimefoldAI/timefold-employee-scheduling#1387. When a model and its visualization live in the same repository, the properties file and the page keys it must match sit side by side, which is the intended end state.

The UI itself is the same set of static files described in xref:running-timefold-solver/service/visualization.adoc[], placed under `src/main/resources/META-INF/resources`.
Once deployed, the platform repackages and serves these files under a `ui/` prefix, so the entry point the platform loads must be exactly `ui/index.html`.

Asset paths under this prefix are single-segment only today: `ui/main.js` is servable, but `ui/assets/main.js` is not.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already fixed, however path references in the .html file need to be relative, not absolute since visualisations don't run under the root domain.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. not /assets/... but ./assets/...

[#_calling_your_api_from_the_iframe]
== Calling your model's API from inside the iframe

The platform injects the following query parameters into the iframe's `src` URL:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer the main case. Yes it works, but the new one is by using messages between the frames. @oemebamo, want me to take this PR to the finish line?

timefold.model.visualization.pages[1].label=Gantt chart
----

Each declared page has three required fields; omitting any of them fails the build.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this help with routing? Are pages a new concept introduced with the specific front-end components? Is the KEY also a tab in the UI?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required now? Or if this is not supplied, does it use "visualization" for whatever is in the UI folder?

@TomCools TomCools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comments

@triceo
triceo removed the request for review from rsynek August 28, 2026 12:21
@oemebamo

Copy link
Copy Markdown
Collaborator Author

Feedback from @muellerd that's useful to incorporate here:

Daniel Mueller at 2026-08-20 10:12 AM When working on the visualization, I was not sure what is feasible for the platform to handle/show. For the household pto planner, I wanted to be able to show detailed information if you click on a day of the calendar. I was thinking about either a popup or something like a sidebar where the information can be shown. Due to the fact that I didn’t know if a sidebar was possible, I went for the popup.

@triceo
triceo requested review from rsynek and removed request for triceo August 31, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants