Skip to content

GDB-14831 add local store persistence#6

Open
plamen-yordanov wants to merge 3 commits into
mainfrom
GDB-14831-add-local-store-persistance
Open

GDB-14831 add local store persistence#6
plamen-yordanov wants to merge 3 commits into
mainfrom
GDB-14831-add-local-store-persistance

Conversation

@plamen-yordanov

@plamen-yordanov plamen-yordanov commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What

Add local storage persistence for diagram state.

Why

This change improves user experience by ensuring that the diagram state is preserved across sessions, allowing users to return to their work without losing progress.

How

  • Implemented DiagramStorageService to handle saving, loading, and clearing the diagram state in localStorage.
  • Introduced EventService to manage events related to clearing the diagram state.
  • Updated ReactodiaApp to utilize the new storage service for persisting diagram data.

Testing

jest/cypress

Screenshots

Checklist

  • Branch name
  • Target branch
  • Commit messages
  • Squash commits
  • MR name
  • MR Description
  • Tests
  • Browser support verified

@plamen-yordanov
plamen-yordanov force-pushed the GDB-14831-add-local-store-persistance branch from 649c348 to 3cb6c34 Compare July 22, 2026 06:40
## What
Add local storage persistence for diagram state.

## Why
This change improves user experience by ensuring that the diagram state is preserved across sessions, allowing users to return to their work without losing progress.

## How
- Implemented `DiagramStorageService` to handle saving, loading, and clearing the diagram state in `localStorage`.
- Introduced `EventService` to manage events related to clearing the diagram state.
- Updated `ReactodiaApp` to utilize the new storage service for persisting diagram data.
- Added tests for `DiagramStorageService` and `EventService` to ensure functionality.

## Testing
jest/cypress
@plamen-yordanov
plamen-yordanov force-pushed the GDB-14831-add-local-store-persistance branch from 3cb6c34 to 910d5cf Compare July 22, 2026 08:07
@plamen-yordanov
plamen-yordanov marked this pull request as ready for review July 22, 2026 12:34
* Local storage getter
*/
private get storage(): Storage | undefined {
return service(WindowService).getWindow()?.localStorage;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I am lately thinking about this.

When will there be no window and is it not better to throw if there is no local storage, than just silently not doing what the client requested without telling him so.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hmm. I had AI move a few classes from the workbench. Apparently it added the | undefined to the type of getWindow and I missed it. It never be undefined in a browser context. I removed it and the optional chaining due to it

subscribeToDiagramChange(model: DataDiagramModel, onChangeCallback: DiagramChangeCallback): Subscription {
let notifyTimer: ReturnType<typeof setTimeout> | undefined;

const onHistoryChange = (): void => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Perhaps also add a comment here why you need to debounce this as it is not clear until you read the comment for the debounce time

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

moved the comment to the method itself

subscribeToClearDiagramStorage(onClear: () => void): Subscription {
const target = service(WindowService).getWindow();
if (!target) {
return () => undefined;

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 does not seem right.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The client will think he subscribed successfully

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed, as we should always have a target

*/
export class WindowService implements Service {
getWindow(): Window | undefined {
return window;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Again, can this be undefined and when?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

never. I removed it and addressed why in the comment above


connectedCallback(): void {
this.renderGraph();
if (this.config) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Maybe throw when there is no config.

Or is there a listener for the config which will reload?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

   * Read once on mount; not watched, as it only sets up the data source and initial canvas.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this will leave us with a permanent error always, as the first connectedCallback runs before @Props are populated, so initially we always throw. That's the reason I added a condition, instead of throwing an error

- removed the undefined type of window and removed the optional chaining due to it
- moved the comment about debounce in the method jsdoc
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.

2 participants