Skip to content
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

300 streamline frontend refresh network calls #836

Merged
merged 51 commits into from
Feb 22, 2024

Conversation

pmarsh-scottlogic
Copy link
Contributor

@pmarsh-scottlogic pmarsh-scottlogic commented Feb 14, 2024

Description

When you first load the website in the browser, or refresh we only send one network request which should grab all the necessary information to get going.

Notes

  • Creates GET /start endpoint which is the single network call the frontend needs to set itself up. It returns the available models, the system roles for all levels and the emails, history and defences for the current level.
  • The above network call acts as the frontend's health check so I've removed the healthcheck stuff from the frontend
  • removes GET /openai/validModels endpoint and all related code (no longer needed)
  • removes GET /systemRoles endpoint and all related code (no longer needed)
  • moves loadBackendData and openHandbook to mainComponent.tsx so that all the /start fetched state stuff can be managed by one component.
  • Adds UseIsFirstRender hook, for using with the useEffect hook. It indicates whether the useEffect is running on the first mount or on the change of a dependency.

Checklist

Have you done the following?

  • Linked the relevant Issue
  • Added tests
  • Ensured the workflow steps are passing

…uest which does the same thing as the health check
@pmarsh-scottlogic pmarsh-scottlogic linked an issue Feb 14, 2024 that may be closed by this pull request
@pmarsh-scottlogic pmarsh-scottlogic marked this pull request as ready for review February 14, 2024 14:09
@chriswilty
Copy link
Member

@pmarsh-scottlogic Reviewing shortly, lunch first...

Copy link
Member

@chriswilty chriswilty left a comment

Choose a reason for hiding this comment

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

Looking good, just a handful of thoughts...

backend/src/controller/startController.ts Outdated Show resolved Hide resolved
{ level: LEVEL_NAMES.LEVEL_1, systemRole: systemRoleLevel1 },
{ level: LEVEL_NAMES.LEVEL_2, systemRole: systemRoleLevel2 },
{ level: LEVEL_NAMES.LEVEL_3, systemRole: systemRoleLevel3 },
];
Copy link
Member

@chriswilty chriswilty Feb 20, 2024

Choose a reason for hiding this comment

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

Hmm. We're sending the actual system roles for all levels, regardless of which level has been beaten? That doesn't feel right, even if that's what we were doing originally. Do we (or can we) send the systemRole for the level when we change level?

It's beginning to feel like we could use some persistent state in the UI, e.g. React Context. It's a bit late for all that now though 😢

Copy link
Contributor Author

Choose a reason for hiding this comment

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

these system roles are for the handbook only. So technincally we only need to send the roles for levels that have been completed when this call happens. Then we'd need to send the next system role when numCompletedLevels increases. Which seems more complex than necessary in my view

Copy link
Member

Choose a reason for hiding this comment

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

I don't think that's complex, as we are sending a payload back to the UI when the level is beaten anyway. It seems silly to hide the system role in the handbook, but it's right there in the network tab if you go looking.

backend/src/controller/startController.ts Outdated Show resolved Hide resolved
frontend/src/components/MainComponent/MainComponent.tsx Outdated Show resolved Hide resolved
frontend/src/components/MainComponent/MainComponent.tsx Outdated Show resolved Hide resolved
isMountRef.current = false;
}, []);
return isMountRef.current;
}
Copy link
Member

Choose a reason for hiding this comment

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

Feels a bit overkill to extract this into its own hook. All you're really doing is storing a ref to indicate when the component has mounted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see no reason to not extract self-contained logic, even if it is trivial. Especially if un-extracting it will take extra effort. Do you think it is less readable this way?

Copy link
Member

Choose a reason for hiding this comment

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

There are plenty of reasons not to extract self-contained logic, particularly into its own file. This one is used in just one component, which is my primary argument. It is no more readable sitting in its own file, than existing as a useRef in the same component that needs it.

Fragmenting your code is something to do when it aids in understanding and readability, because your code is becoming complex. But even in that case, there is rarely much benefit in extracting small pieces of code; instead you will benefit most from separating concerns.

I would like you to learn that refactoring can make things worse; keep related code co-located until such time as you find yourself repeating / copying logic. I am a strong advocate for keeping things simple; the Three Strikes rule is a good one to follow in cases like this:
https://en.wikipedia.org/wiki/Rule_of_three_(computer_programming)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting... This feels like something I'd have to learn the hard way to properly internalise it, but I'll take it on face value for now!

Copy link
Member

@chriswilty chriswilty Feb 22, 2024

Choose a reason for hiding this comment

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

I have learned the hard way ;)

In the back-end code you've done a whole heap of good separation-of-concerns type refactoring. Front-end code is a slightly different beast, and that also takes some getting used to. There's a pretty good argument made in the ReScript docs to keep project / component structure as flat as possible, co-locate related things, and generally not worry too much about splitting files, to avoid exactly this kind of debate!

Copy link
Member

Choose a reason for hiding this comment

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

(Chris keeps quietly spreading the word about ReScript)

frontend/src/models/combined.ts Outdated Show resolved Hide resolved
frontend/src/service/startService.ts Outdated Show resolved Hide resolved
Copy link
Member

@chriswilty chriswilty left a comment

Choose a reason for hiding this comment

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

This all seems great 💎

Still the reservation about extracting the hook, otherwise very happy to approve.

Copy link
Member

@chriswilty chriswilty left a comment

Choose a reason for hiding this comment

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

Very happy with this, took some working out 🏆

@pmarsh-scottlogic pmarsh-scottlogic merged commit 73e8d8e into dev Feb 22, 2024
2 checks passed
@pmarsh-scottlogic pmarsh-scottlogic deleted the 300-streamline-frontend-refresh-network-calls branch February 22, 2024 10:49
chriswilty pushed a commit that referenced this pull request Apr 8, 2024
* adds placeholder levelState endpoint

* fill out handleGetLevelState

* adds reminder comment

* remove valid models and system roles from level state endpoint

* add service to get levelSTate in frontend

* adds leveStateService to index

* corrects levelState url in frontend

* further corrects levelState url in frontend

* fixes typo in comment

* renames levelState to handleStart

* adds models and system roles back to start request

* updates frontend service with changed name and added models and system roles

* replace models and system roles front end calls with the start endpoint

* erases all trace of system role endpoint

* erases all trace of valid model endpoint

* renames models to availableModels

* removes helth check from frontend and adds catch to the handshake request which does the same thing as the health check

* fix names from levelState to getStart in backend

* only loads level info after first mount

* separate logic for processing new level data from fetching it

* remove some comments

* moves main body key to App component

* Revert "moves main body key to App component"

This reverts commit 6e29718.

* moves loadBackend data to maincoomponent

* simplifies args to processBackendLevelData

* converts chatMessageDTOs to chatMessages before returning from the service

* moves messages state back to MainComponent

* moves System roles state and openHandbook to mainComponent

* removes redundant try catch and moves console log

* puts startResponse in new models file combined.ts

* removes comment

* uses object destructuring to shorten declaration

* renames to getValidOpenAIModels()

* refactors loadBackendData

* adds list of defences to show in level 3 by id

* small rename

* Revert "small rename"

This reverts commit 60440bb.

* Revert "adds list of defences to show in level 3 by id"

This reverts commit a17d13b.

* dinstinguishes between Defence and DefenceDTO. converts DTO to defence in the frontend service

* fixes console log

* remove defences_shown_level3

* clarifies nonModelDefences

* renames ALL_DEFENCES to DEFAULT_DEFENCES

* replaces a some with an includes

* uses object destructuring to simplify startService

* renames history to chatHistory in startResponse

* fix mocking for getValidOpenAIModels

* fixes different instance of same mocking problem

* moves isFirstRender logic out of hook

* sets isFirstRender at the the right place
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.

Streamline frontend refresh network calls 🛠🛠🛠
2 participants