Repository navigation
GSoC'26 : As-Of Frontend Implementation Complete #36
Replies: 4 comments
|
Hi @massimiliano-cannata @danistrigaro @ClaudioPrimerano , It's been a week since I asked about the chart behavior in As-Of mode and since I want to keep my GSoC timeline on track, I'm going ahead with what I believe are the most sensible defaults. I'm sharing them here so you can redirect me if anything looks wrong before the PR is up. My planned approach: Fetching observations in snapshot mode - I'll apply both $as_of={asOfDate} (for transactional consistency) and $filter=phenomenonTime le {asOfDate} (to exclude readings with a future phenomenon time). If $as_of has no effect on Observations at the backend level, the second filter still guarantees the correct result. Default chart window - When the chart opens in As-Of mode, the default range will be [asOfDate - 7 days, asOfDate], mirroring the existing live-mode logic where asOfDate simply takes the place of "now." Date range picker - I'll hard-clamp the picker's right bound to asOfDate so users can't select dates beyond the snapshot. This makes the temporal boundary explicit rather than silently filtering server-side. Thing selector inside the chart modal - It will continue showing all live things (checking historical existence for every thing upfront would require N extra API calls). If a selected thing didn't exist at the snapshot date, the chart will show a clear "no data at this snapshot" state. I'll open a PR shortly. Let me know if you'd prefer a different approach on any of these! Thanks |
|
complete as_of UI PR , please have a look. |
|
hey @ClaudioPrimerano please review and merge this PR (based on whatever we discussed and i showed during the meeting) and if needs any changes then do let me know. |
Hello @massimiliano-cannata @danistrigaro @ClaudioPrimerano The red low-opacity box in the screenshot is meant to represent the change band — the specific time range where the two snapshots have different values. I added it so the user can quickly see where the change occurred on the chart, instead of having to identify the differences by comparing the two lines manually. I kept the opacity low so it highlights the region without distracting from the data. I also wanted to highlight the placement of the “Compare with Live” and “Compare with snapshot” controls. I feel their current position, just below the snapshot/date selection and above the chart, makes the comparison action clear and keeps it visually connected to the graph. Would love to hear if this works well. |

Uh oh!
There was an error while loading. Please reload this page.
Hi @massimiliano-cannata @danistrigaro @ClaudioPrimerano
I've completed the frontend implementation of the As-Of temporal navigation feature and wanted to share a summary of what's been built.
Before raising a PR, I'll integrate the Observation Graph/Chart behavior for snapshot mode as well. However, I have a few questions regarding its expected behavior, and I'd like to clarify them before proceeding with the implementation.
What's Been Implemented
State management (AsOfContext): A React context (
AsOfContext) holds the globalasOfDate: string | nullandisSnapshot: boolean. All components that need to react to snapshot mode consume this context via theuseAsOf()hook.Navbar UI (AsOfNavbarButton + AsOfDropdown): A button in the navbar lets users enter snapshot mode by picking a datetime. It uses the same date-time picker style as the existing chart modal for consistency. Selecting a date activates snapshot mode; a "Return to Live" button clears it.
Adapter pattern for mock/real data switching (
asOfAdapter.ts): To decouple the UI from the backend's current development state, I implemented an adapter pattern. A single environment variable (NEXT_PUBLIC_VERSIONING_ENABLED=true) switches between:GET /Things({id})?$as_of={date}&$expand=Datastreams(...)to resolve the thing's metadata snapshot.Thing metadata resolution (
useAsOfThinghook): When a thing is selected in snapshot mode, this hook resolves the thing's name, description, sensors, and datastreams as they existed atasOfDateviaactiveAdapter.resolveThing().Commit history & Timeline Scrubber (
useAsOfCommits+TimelineScrubber): Fetches the commit history for a thing fromGET /Things({id})/Commitand renders a horizontal scrubber with tick marks at each commit point. Users can drag the scrubber to navigate the thing's history.Existence validation (
AsOfExistenceDialog): IfasOfDatefalls before the thing's creation or after its deletion, the adapter returns anexistenceStateof'not-yet-created'or'deleted'. A floating dialog appears with a "Jump to nearest valid date" recovery action.DatastreamTable integration: In snapshot mode, the table shows the resolved snapshot thing's datastreams, hides all write actions (create/edit/delete), and shows an amber "Snapshot mode - read-only" banner with the formatted snapshot datetime.
Questions About the Chart in As-Of Mode
Before integrating the Observation Graph into snapshot mode, I have a few implementation questions regarding the expected behavior.
Q1 : Should
$as_ofbe included when fetching observations?The chart currently fetches observations using:
For snapshot mode, my initial plan is to:
$as_of={asOfDate}, andphenomenonTimefilter never exceedsasOfDate.However, this depends on whether Observations themselves are versioned.
Does
$as_ofhave any effect when querying/Observations(i.e. does it return the observation state that existed at that system time), or should I simply rely onphenomenonTime <= asOfDate?Q2 : What should the default chart window be in snapshot mode?
In live mode, the chart defaults to showing the previous 7 days ending at the most recent observation.
In snapshot mode, should the snapshot timestamp become the new "present", so the default window becomes:
[asOfDate − 7 days, asOfDate]
or would you prefer a different default (for example, the entire lifetime of the datastream up to the snapshot)?
Q3 : Should the chart's DateRangePicker be restricted in snapshot mode?
In live mode, users can freely select any date range.
In snapshot mode, should the DateRangePicker prevent selecting an end date later than
asOfDate, or should the UI remain unrestricted while the backend simply clamps the returned observations toasOfDate?Q4 : Should the Thing selector inside the ChartModal be snapshot-aware?
The chart currently allows switching between Things for comparison.
In snapshot mode, should this selector:
asOfDate?I wasn't sure which behavior better matches the intended temporal navigation experience.
These questions are roughly ordered by implementation impact:
Once these are clarified, I'll complete the chart integration and then open the PR.
All reactions