-
Notifications
You must be signed in to change notification settings - Fork 15
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
#81 (1) JsonForms skeleton #148
Conversation
client/packages/common/package.json
Outdated
"@material-ui/icons": "^4.11.3", | ||
"@mui/icons-material": "^5.8.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need the icons, I'll try and remove in next PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please! the icons packages is huge and we have deliberately created only the icons we need in order to avoid it
@@ -8,6 +8,7 @@ interface ButtonProps { | |||
label: string; | |||
width?: string; | |||
height?: string; | |||
color?: 'primary' | 'secondary' | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll notice this isn't used in this PR -- I'm using it for the Arrays to create the "Add item" button -- in next PR
stringSubstitution: ( | ||
parameterisedString: string, | ||
data: { [key: string]: any }, | ||
fallback = 'Not found' | ||
) => | ||
parameterisedString.replace(/\${(.*?)}/gm, (_: string, match: string) => | ||
extractProperty(data, match, fallback) | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little copy-paste from Conforma ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
and.. oh, right. the name stringSubstitution
referenced earlier did not make me expect this kind of functionality. Something like 'formatTemplateString' or 'templateSubstitution' 🤷 dunno
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good point, I've never been particularly happy with that name. Changed it to formatTemplateString
client/packages/common/src/ui/forms/JsonForms/components/Label.tsx
Outdated
Show resolved
Hide resolved
Don't see any reason to delay while waiting for a fully feature complete version. The demo server for the feature site has the webhook disabled, so will only be updated manually. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import { FormLabel, Box } from '@mui/material'; | ||
import { BaseDatePickerInput } from '@openmsupply-client/common'; | ||
|
||
export const dateTester = rankWith(5, isDateControl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a new user to this - what is a tester
?
Can you add a comment to explain?
Could they be grouped in a testers file? Would that make it clearer? or is it helpful to have them next to the component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tester -- function that returns a number based on whether or not a predicate is true (In this case it will return 5 if isDateControl
, otherwise it returns -1). Then for each form element, the tester that returns the highest number gets rendered by the component matched to that tester (in "renderers" prop), i.e.
{ tester: stringTester, renderer: TextField },
{ tester: selectTester, renderer: Selector },
{ tester: groupTester, renderer: Group },
{ tester: labelTester, renderer: Label },
{ tester: dateTester, renderer: Date },
{ tester: arrayTester, renderer: Array }
I thought since we're generally going to have testers coupled to components in a one-to-one manner, it made sense to keep each tester with its associated component.
I did make a more generic tester for matching custom fields (in uiSchema) to components, but it wasn't being used in here. I might include it in a later PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, right. thanks - wasn't clear to me from the name alone!
<BaseDatePickerInput | ||
value={data} | ||
onChange={e => handleChange(path, e)} | ||
inputFormat="dd/MM/yyyy" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hard-coded format : can it be intl based? can it be configurable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually just copied straight from common/src/ui/components/inputs/DatePickers/DatePickerInput/DatePickerInput.tsx
😉
So yeah, we should localise them both at some point.
import { MaterialLayoutRenderer } from '@jsonforms/material-renderers'; | ||
import { Box, Typography } from '@mui/material'; | ||
|
||
export const groupTester = rankWith(4, uiTypeIs('Group')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, these things aren't making sense. what is 4
here?
marginBottom: 2, | ||
}} | ||
> | ||
<Typography width="40%" fontSize="1.2em" textAlign="right"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we may have to use ems throughout 🤔
Could the font size here come from the theme?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, have re-styled the "subtitle" variant in theme with this fontSize -- didn't look like it was being used elsewhere.
Would like to organise the typography a bit better overall at some point: msupply-foundation/openmsupply-client#1149
return ( | ||
<Box | ||
sx={{ | ||
maxWidth: 500, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the maxWidth is fairly specific, just wondering if that will cause problems later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved these values into a "styleConstants" file so we can update them easily if we need to.
Also -- if we need a wider "Group" in future, we can always make "width" a new property in uiSchema which the component can use, or have an alternative component "WideGroup". (for one that spans 2 columns, perhaps?)
stringSubstitution: ( | ||
parameterisedString: string, | ||
data: { [key: string]: any }, | ||
fallback = 'Not found' | ||
) => | ||
parameterisedString.replace(/\${(.*?)}/gm, (_: string, match: string) => | ||
extractProperty(data, match, fallback) | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
and.. oh, right. the name stringSubstitution
referenced earlier did not make me expect this kind of functionality. Something like 'formatTemplateString' or 'templateSubstitution' 🤷 dunno
if (isLoading) return <BasicSpinner />; | ||
|
||
return !!data ? ( | ||
return !error ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
controversial maybe.. flip the logic?
return error ? null : (<blah />);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sure -- that's just a small personal preference -- in ternarys I generally like to put the "expected" or "preferred" outcome first so the "bad" outcome is tucked nicely out of the way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah me too - and then I fight with the desire to put the positive assertion in the conditional - preferring if error
to if !error
- and also for having the small bit first, so that it's easier to read. In cases like this where the first condition is big, it's hard to see the little null
.
as you were then.. real no need to change
@@ -9,8 +9,8 @@ import { | |||
Fade, | |||
NothingHere, | |||
createQueryParamsStore, | |||
useFormatDateTime, | |||
ColumnAlign, | |||
// useFormatDateTime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add the DOB back in? It's working and wanted, and I'm not sure why it is removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Yes, that's what I've been trying to fix with the Array component. I've made a much nicer, more consistent UI using an Accordion -- but I still haven't cracked how to reliably (I can do it unreliably lol!) pass everything through to the inner elements. So that'll be in another PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only had a look at the UI and looks great! yes please go ahead and merge I will have a more detailed look later
This just provides the basic skeleton for the JSON forms as outlined here.
Suggest we use this as a base for subsequent PRs, then merge them as one once this area is "complete"
Will create issues for remaining f/e items from #81.
Here we have:
useJsonForms
hookdocument
endpoint is readyTo test:
Just click on a name in the Patient list and the Modal will display the hard-coded "Patient" data using the associated schemas. There's a lot of clutter in the form currently, due to the default Array component.