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

913: Document Viewer improvements #916

Merged
merged 4 commits into from
Jul 15, 2024
Merged

913: Document Viewer improvements #916

merged 4 commits into from
Jul 15, 2024

Conversation

chriswilty
Copy link
Member

@chriswilty chriswilty commented Jul 9, 2024

Description

Documents metadata are now returned in the (sandbox) level data payload. This results in two improvements:

  • no need to request metadata every time the Document Viewer is opened
  • first document can be requested as soon as the viewer opens, so we never need to see a loading indicator for the metadata fetch

This might be easiest viewed per commit, instead of all in one go.

resolves #913

Notes

  • There were case-sensitivity typos in DocumentMeta model properties, causing a redundant HEAD request for every document fetched; these have been corrected, so now DocViewer code can use fileType to know what renderer to use, and the HEAD request is not needed
  • Improvements made to frontend service code, to remove some duplicated boilerplate - now we have separate get and post functions (copied over from the cloud infra feature branch)
  • Stronger type safety for responses in backend controller code

Checklist

Have you done the following?

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

@chriswilty chriswilty self-assigned this Jul 9, 2024
filetype: fileType === 'csv' ? 'text/csv' : fileType,
return {
fileName: file,
fileType: fileType === 'csv' ? 'text/csv' : fileType,
Copy link
Member Author

Choose a reason for hiding this comment

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

Typo fixes! This was causing redundant HEAD requests in the UI.

fileURLToPath(new URL('../../resources/documents', importMetaUrl())),
{
cacheControl: true,
maxAge: 604800000, // 7 days as millis
Copy link
Member Author

Choose a reason for hiding this comment

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

Documents rarely change, so we can tell the browser to cache them.

}: {
documents?: IDocument[];
closeOverlay: () => void;
}) {
const [documentIndex, setDocumentIndex] = useState<number>(0);
Copy link
Member Author

@chriswilty chriswilty Jul 9, 2024

Choose a reason for hiding this comment

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

Interesting story: I tried moving this "current document index" into the parent component and passing it in as a prop, so that the viewer would remember where you were when reopening. Didn't work - it actually made things worse as the prev and next buttons no longer changed the current page.

Why? Because even though the JSX declaring our DocumentViewBox belongs to the parent (MainComponent.tsx), we pass that as children to Overlay component, which is rendered by the grandparent (App.tsx). We can store the state in the parent, and when calling setDocumentIndex the parent is indeed updated, and in theory DocumentViewBox will receive the new prop. But there is nothing to trigger App component to update: its state does not change, it has no props, and it is not using context. So Overlay doesn't update either, meaning it continues to render its now outdated content with the old prop values. Only when you close and re-open it do you see the correct page, which shows that the buttons are actually updating the state.

We cannot simply lift the state and the DocumentViewBox JSX into App, because the documents are fetched in the level/start request which is made by MainComponent. This kind of limitation has come up before - see mainBodyKey state in MainComponent - and is another example of how storing level state in MainComponent with a useState hook, and passing it all down via prop drilling, is making life uncomfortable. We might be better off switching to a context-based store instead, for level state.

Copy link
Contributor

Choose a reason for hiding this comment

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

Always teaching!
well explained

body?: T;
};

async function get(
Copy link
Member Author

Choose a reason for hiding this comment

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

This is all starting to look like axios! But hey, our implementation here is really lightweight and focused.

Comment on lines +10 to +11
const level = validateLevel(res, req.query.level);
if (level === null) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

I like this pattern

fileName,
fileType,
uri: `${baseUrl}${PATH}/${folder}/${fileName}`,
}) as IDocument
Copy link
Contributor

Choose a reason for hiding this comment

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

nice that we're using the proper types given by the api

Copy link
Contributor

@pmarsh-scottlogic pmarsh-scottlogic left a comment

Choose a reason for hiding this comment

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

Looks great! Lovely bit of optimisation, and well explained.

Didn't scour it with a magnifiying glass (or run it, I'm afraid) but the code all looks sensible.

@chriswilty chriswilty merged commit e8600c4 into dev Jul 15, 2024
4 checks passed
@chriswilty chriswilty deleted the 913-docviewer-fixes branch July 15, 2024 08:58
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.

Doc Viewer shows "unable to fetch documents" error during initial load
2 participants