Skip to content

Conversation

@mabaasit
Copy link
Collaborator

Description

Checklist

  • New tests and/or benchmarks are included
  • Documentation is changed or added
  • If this change updates the UI, screenshots/videos are added and a design review is requested
  • I have signed the MongoDB Contributor License Agreement (https://www.mongodb.com/legal/contributor-agreement)

Motivation and Context

  • Bugfix
  • New feature
  • Dependency update
  • Misc

Open Questions

Dependents

Types of changes

  • Backport Needed
  • Patch (non-breaking change which fixes an issue)
  • Minor (non-breaking change which adds functionality)
  • Major (fix or feature that would cause existing functionality to change)

@github-actions github-actions bot added the feat label Jun 26, 2025
Comment on lines +107 to +108
// So, when exporting, we need to include those defs as well so that
// edge markers are exported correctly.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wouldn't it be easier to hide what we don't need instead of doing this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we make this configurable in the diagramming package?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Wouldn't it be easier to hide what we don't need instead of doing this?

I'll evaluate this, last time (in poc) i checked this, it did not give me good results.

Can we make this configurable in the diagramming package?

These custom marker are rendered here in the package. I am not sure if i follow what you mean by making it configurable?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, comment somehow attached to the wrong place, should've been this part:

It excludes diagram title, minmap, and other UI elements

We're doing all this to avoid including controls in the diagram screenshot. Can we change diagramming package to allow us to render it with hidden controls? Then you don't need to do anything to target an element that doesn't include everything that you need

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah, yeah that should be possible with the package. but again it depends on if we are able to export the root container (.react-flow) and if not, then maybe we don't need it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried to do this and was not able to get it to export correctly using this approach.

waitForFileDownload,
} from '../helpers/downloads';
import { readFileSync } from 'fs';
import { recognize } from 'tesseract.js';
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For current changes in this file, I ended up doing png export e2e tests in this PR. While exploring OCR testing, wdio relies on tesseract.js. So i added it as a dep and as we are downloading an image, it makes sense to do it this way (as compared to using wdio api to read contents from an image on webpage).

I ran this test many time locally to ensure it does not fail randomly. Collection name changes in this file are mainly because it struggles to read testCollection1 (reads it as testCollectionl)

Also, when @paula-stacho's positioning PR lands, it will ensure that nodes don't overlap and we will not have any unexpected failing assertions.

@mabaasit mabaasit added the no release notes Fix or feature not for release notes label Jun 26, 2025
@mabaasit mabaasit marked this pull request as ready for review July 2, 2025 10:12
@mabaasit mabaasit requested a review from a team as a code owner July 2, 2025 10:12
): Promise<string> {
return new Promise<string>((resolve, reject) => {
export function getExportPngDataUri(diagram: DiagramInstance): Promise<string> {
return new Promise<string>((resolve, _reject) => {
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why we're going to the Promise resolve/reject here? I'm thinking it could lead to an uncaught exception. Could we instead have the cleanup in a finally or catch block?

We could do await something like the rafraf as well and await the toPng.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What would you recommend in this case? I only want to resolve once dom has been converted to a data uri (and as such show loading state to the user). For clean up, its already in place where we export.

Copy link
Member

Choose a reason for hiding this comment

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

I would recommend async/await here with try/catch. I find it makes the code easier to read through and the error handling less prone to be uncaught.

}, [exportFormat, onCloseClick, model, diagramLabel]);
}, [onCloseClick]);

const onExport = useCallback(async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is way too much logic in the UI here (like if you see that you're keeping abort controllers in render, you probably should start thinking about that), this should really be an action in the store instead

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, i'll add another slice for export. Or, I can do it as a follow up if that sounds okay to you.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Follow-up sounds good, let's not hold this code in the branch for too long 👍

const diagram = useDiagram();
const [isExporting, setIsExporting] = useState(false);
const abortControllerRef = useRef<AbortController | null>(null);
const toast = useToast();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Use our openToast instead, not sure how are we even exporting this one, we really shouldn't

}));

const reject = (error: Error) => {
document.body.removeChild(container);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems like we're missing clean-up on resolve, this should probably be in a finally block

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah, @Anemy also mentioned same and that time i completely misunderstood this. i added this in 6136ff4 along with other fixes. Regarding useToast hook, i'll do a follow up to remove it from compass-components as its not being used elsewhere.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good!

i'll do a follow up to remove it from compass-components

Just FYI, I already did in eslint update PR, so no need to worry about this (was in the way of some new issues that update started to show there)

expect(text).to.include('jint');
// it does not correctly recognize `iString` and only returns `String`.
// its already good enough to verify this for now and if it flakes
// more, we may need to revisit this test.
Copy link
Collaborator

Choose a reason for hiding this comment

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

that was unlucky naming on our part 😅 it'd be easier to OCR full words rather than lone letters, especially tricky ones like 'i'. now that it's used everywhere, I assume it'd be too much hassle to rename

Copy link
Collaborator

@gribnoysup gribnoysup left a comment

Choose a reason for hiding this comment

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

Looks good taking into account some follow-ups we're planning to do

Comment on lines +90 to +92
const viewportElement = container.querySelector(
'.react-flow__viewport'
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: instead of relying on arbitrary frames you can probably wait for this element to be in the view (similar to what we do in tests sometimes)

}));

const reject = (error: Error) => {
document.body.removeChild(container);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: you don't need it here now that you have it in finally

@mabaasit mabaasit merged commit 0822820 into main Jul 3, 2025
55 of 58 checks passed
@mabaasit mabaasit deleted the COMPASS-9449-export-to-png branch July 3, 2025 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat no release notes Fix or feature not for release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants