Skip to content

perf: fetch server side data for workflow details page #20778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

TusharBhatt1
Copy link
Contributor

@TusharBhatt1 TusharBhatt1 commented Apr 20, 2025

What does this PR do?

This PR moves all the /workflows/[id] data fetching to server side.

Visual Demo (For contributors especially)

Before :
image
After:
image

dynamic-worklflows.mp4

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

Summary by mrge

Moved all data fetching for the /workflows/[id] page to the server side to improve performance and reliability.

  • Refactors
    • Replaced client-side data fetching with server-side calls for workflow details, user info, and related data.
    • Updated components to accept server-fetched data as props.

Copy link

vercel bot commented Apr 20, 2025

@TusharBhatt1 is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Apr 20, 2025
@graphite-app graphite-app bot requested a review from a team April 20, 2025 16:31
Copy link
Contributor

github-actions bot commented Apr 20, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "Perf/fetch server side data for dynamic webflow page". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@keithwillcode keithwillcode added the community-interns The team responsible for reviewing, testing and shipping low/medium community PRs label Apr 20, 2025
@dosubot dosubot bot added performance area: performance, page load, slow, slow endpoints, loading screen, unresponsive workflows area: workflows, automations labels Apr 20, 2025
Copy link

@mrge-io mrge-io bot left a comment

Choose a reason for hiding this comment

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

mrge found 3 issues across 5 files. View them in mrge.io

Copy link

graphite-app bot commented Apr 20, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (04/20/25)

1 reviewer was added to this PR based on Keith Williams's automation.

"Add community label" took an action on this PR • (04/20/25)

1 label was added to this PR based on Keith Williams's automation.

@TusharBhatt1 TusharBhatt1 changed the title Perf/fetch server side data for dynamic webflow page perf: fetch server side data for dynamic webflow page Apr 20, 2025
teamId: workflow?.team?.id,
},
{ enabled: !verifiedEmailsProp }
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to server side

Copy link
Contributor

@hbjORbj hbjORbj left a comment

Choose a reason for hiding this comment

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

Great job Tushar! That was fast. But this requires some changes.

if (!workflowData) return notFound();

const isOrg = workflowData?.team?.isOrganization ?? false;
const teamId = workflowData?.teamId ?? undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: what happens when teamId is undefined? does it break anything? if so, shouldn't we show 404 page?

Copy link
Contributor Author

@TusharBhatt1 TusharBhatt1 Apr 21, 2025

Choose a reason for hiding this comment

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

In that case it returns [] - empty array same as what we have as fallback rn , nothing's breaking

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can improve it by skipping the verifiedNumbers call if teamId is undefined and return [] straight away

@@ -34,7 +34,7 @@ function UsersTable({ setSMSLockState }: Props) {
const { data: usersAndTeams } = trpc.viewer.admin.getSMSLockStateTeamsUsers.useQuery();

if (!usersAndTeams) {
return <></>;
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

can you explain why this change was necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just for better readability/code quality

const [isPhoneNumberNeeded, setIsPhoneNumberNeeded] = useState(false);
const [isSenderIdNeeded, setIsSenderIdNeeded] = useState(false);
const [isEmailAddressNeeded, setIsEmailAddressNeeded] = useState(false);
const { data: actionOptions } = trpc.viewer.workflows.getWorkflowActionOptions.useQuery();
Copy link
Contributor

@hbjORbj hbjORbj Apr 21, 2025

Choose a reason for hiding this comment

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

This query should stay client-side because the "Add action" Dialog should not block the initial load. For example, imagine that the query fetching for Add Action Dialog failed. Now it blocks the entire page load. Handling a query failure is another topic, but I am mentioning it to help you decide which is something you should fetch server-side vs client-side. The more server-side fetching we do, the slower the initial load is, and hence we should determine carefully which queries to turn to server-side and keep client-side.

So, Please think about this for other queries you switched to server-side in this PR and make changes accordingly!

Screenshot 2025-04-21 at 11 04 31 AM

Copy link
Contributor Author

@TusharBhatt1 TusharBhatt1 Apr 21, 2025

Choose a reason for hiding this comment

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

So basically we where doing this same call two times : one for the page (form) and another for this Dialog so I just removed it from here and passed from the page - I understand your concerns but that's not the case here

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you understood my point. I am saying we should not have workflowCaller.getWorkflowActionOptions() in RSC.

Copy link
Contributor Author

@TusharBhatt1 TusharBhatt1 Apr 21, 2025

Choose a reason for hiding this comment

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

You mean - we should call getWorkflowActionOptions client side and pass to this modal as well (as we are already doing in this PR) , sounds good btw

image
image

Copy link
Contributor

Choose a reason for hiding this comment

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

You can simply let const { data: actionOptions } = trpc.viewer.workflows.getWorkflowActionOptions.useQuery(); just stay in packages/features/ee/workflows/components/AddActionDialog.tsx unless you have a better optimization in mind.

Copy link
Contributor Author

@TusharBhatt1 TusharBhatt1 Apr 21, 2025

Choose a reason for hiding this comment

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

You can simply let const { data: actionOptions } = trpc.viewer.workflows.getWorkflowActionOptions.useQuery(); just stay in packages/features/ee/workflows/components/AddActionDialog.tsx unless you have a better optimization in mind.

Then we'll end up doing two calls for actionOptions as soon as the page renders (current behaviour on prod) - one in WorkflowDetailsPage.tsx and another in AddActionDialog.tsx (we require this data on both places)

I have updated it to call just once just inside WorkflowDetailsPage and simply pass it to AddActionDialog as prop
Thoughts ?

Copy link
Contributor

@hbjORbj hbjORbj Apr 21, 2025

Choose a reason for hiding this comment

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

That sounds good but is it necessary? Client-side trpc queries are cached, no? especially since these two queries happen almost at the same time?

I love to avoid prop drilling as much as possible unless it's necessary

Would be great to have you test this quickly 🙏

Copy link
Contributor Author

@TusharBhatt1 TusharBhatt1 Apr 21, 2025

Choose a reason for hiding this comment

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

The API calls increases making them look lot more - having one looked clean to me , anyways I have added an trpc call in the Dialog as well

@github-actions github-actions bot marked this pull request as draft April 21, 2025 14:11
Copy link
Contributor

github-actions bot commented Apr 21, 2025

E2E results are ready!

@TusharBhatt1 TusharBhatt1 marked this pull request as ready for review April 21, 2025 14:38
@TusharBhatt1
Copy link
Contributor Author

Great job Tushar! That was fast. But this requires some changes.

Thanks @hbjORbj , I have addresed them all - can you have a look

@hbjORbj hbjORbj changed the title perf: fetch server side data for dynamic webflow page perf: fetch server side data for workflow details page Apr 21, 2025
Copy link

@mrge-io mrge-io bot left a comment

Choose a reason for hiding this comment

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

mrge found 3 issues across 7 files. View them in mrge.io

}
}, [isPending]);
setFormData(workflow);
}, []);
Copy link

Choose a reason for hiding this comment

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

Empty dependency array in useEffect where workflow dependency is used

// teamId: workflow?.team?.id,
// });
// } catch (err) {}
const [verifiedEmails, verifiedNumbers, eventsData, user, actionOptions] = await Promise.all([
Copy link

Choose a reason for hiding this comment

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

Using index-based destructuring from Promise.all results can be error-prone if the order of promises changes in the future.

// teamId: workflow?.team?.id,
// });
// } catch (err) {}
const [verifiedEmails, verifiedNumbers, eventsData, user, actionOptions] = await Promise.all([
Copy link

Choose a reason for hiding this comment

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

Missing error handling for Promise.all. If any of these async calls fail, the entire page will fail.

@hbjORbj
Copy link
Contributor

hbjORbj commented Apr 21, 2025

@TusharBhatt1 Please review my comments more carefully and only ping me after more careful review of your code yourself. As I mentioned before, let's minimize the number of ping pongs as much as possible. Don't wanna spend 7-8 ping-pongs on a small change like the last time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community Created by Linear-GitHub Sync community-interns The team responsible for reviewing, testing and shipping low/medium community PRs performance area: performance, page load, slow, slow endpoints, loading screen, unresponsive ready-for-e2e workflows area: workflows, automations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants