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

Feature/download template redesign #342

Open
wants to merge 8 commits into
base: development
Choose a base branch
from

Conversation

gqcorneby
Copy link

@gqcorneby gqcorneby commented Jan 22, 2025

📌 References

📝 Implementation

  • added a section component to reuse styles and collapse function for the form sections
  • divided fields into sections
  • rearranged advanced options
  • updated toggle filterOrgUnits logic. Remove clearing of populate, populate dates, and selectedOrgUnits (more notes in reviewers section)
  • hide populate section until an orgUnit is selected. Previously depended on the org unit checkBox

🔥 Notes for the reviewer

  • hide populate section until an orgUnit is selected, otherwise the section is empty
  • updated behavior of selecting organization unit.
    • PREVIOUSLY: when toggled, the following were cleared: selectedOrgUnits, populate, populate dates
    • NOW: collapsing implies a visual change not data change, so I removed data updates
  • I opted to use up down arrows instead of left right as indicated in the task document. Seems to fit more with how the section collapses.
  • I used the "Organisation Unit" label beside the toggle with an indicator of how many is selected (found it useful while testing so included it for now)

📹 Screenshots/Screen capture

image

image

image

📑 Others

- add sections in download template page
- collapsible orgunit section instead of a checkbox
- rearrange advanced options
@gqcorneby gqcorneby requested review from tokland and adrianq January 22, 2025 08:38
@ifoche
Copy link
Member

ifoche commented Jan 22, 2025

Copy link

@tokland tokland left a comment

Choose a reason for hiding this comment

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

[code-only review] Looking good! just some minor details:

iconPos = "right",
classProps = {},
arrowStyle = "upDown",
}: SectionProps) => {
Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

That's not wrong at all, but typically we prefer to write props: SectionProps here and unpack in the first line of the component, so the signature stays single-line and more readable (subjective!).

arrowStyle?: arrowStyle;
}

export const Section = ({
Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

I see you preferred to define children explicitly in the props instead of using React.FC. We typically use FC, BUT since it adds always children (that's why some people don't like FC), we lose some control, so let's go with this. Eventually, we can decide on creating our own "FCWithProps" or whatever, but no need to to it here.

return (
<Paper elevation={elevation} className={`${classes.paper} ${classProps.section}`}>
<div
className={`${classes.header} ${leftIcon} ${classProps.header} ${isOpen ? "" : classes.noBorder}`}
Copy link

Choose a reason for hiding this comment

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

If I am not mistaken, when leftIcon is null, it will appear "null" in the class list. There are packages for that (classnames), but you can also do this: _.compact([name1, name2, name3]).join(" ")

{title}
{collapsible && !leftIcon && <CollapsibleToggle isOpen={isOpen} arrowStyle={arrowStyle} />}
</div>
<div className={`${classProps.content}`} style={{ display: isOpen ? "" : "none" }}>
Copy link

Choose a reason for hiding this comment

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

Whenever possible, we strive for immutable props (memoized components will benefit from that).

arrowStyle: "upDown" | "rightLeft";
}

export const CollapsibleToggle = ({ isOpen, arrowStyle }: CollapsibleToggleProps) => {
Copy link

Choose a reason for hiding this comment

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

It's not used externally, right? we can remove the export.

@@ -81,6 +83,7 @@ export const TemplateSelector = ({
showLanguage: false,
}
);
const [showAdvancedOptions, setShowAdvancedOptions] = useState<boolean>(true);
Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

Not wrong, but we don't typically pass a type if TS can infer it.

// const isCustomProgram = state.templateType === "custom" && state.type !== "dataSets";
// const populate = isCustomProgram && filterOrgUnits;
// setState(state => ({ ...state, populate }));
// clearPopulateDates();
Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

Typically, commented code should be simply removed, we can use git to go back (We may do this for some temporal/testing code, but not in general)

{models.length > 1 && (
<Section
title={<h3 className={classes.title}>{i18n.t("Template")}</h3>}
classProps={{ section: classes.section }}
Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

[immutable props] I think we can simply pass "classes" here (unless we really don't want to pass the other keys that Section uses (header?). If that's the case, we can use useMemo to build the object. We would be using useMemo not because it's a costly operation, but to keep the value/prop immutable.

label={i18n.t("Split data entry tabs by section")}
/>
)}

Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

[not to change] The return JSX expression of this component is huuuge (608-294 lines). That's not your fault, you are just moving already existing parts. So this is a note for the future: whenever a component grows too much, let's abstract conceptual units and create new components. But again, it does not make sense to do it now (it's more fitting for a general refactoring/polishing task)

elevation = 1,
iconPos = "right",
classProps = {},
arrowStyle = "upDown",
Copy link

@tokland tokland Jan 22, 2025

Choose a reason for hiding this comment

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

About the expand/collapse styles, I checked what DHIS2 does, and... it depends:

orgUnits tree (icon: left the name): right/down
maps (icon: top-right): up/down

https://play.im.dhis2.org/stable-2-40-6/dhis-web-maintenance/index.html#/list/organisationUnitSection/organisationUnit

https://play.im.dhis2.org/stable-2-40-6/dhis-web-maps/#/GlCLRPPLsWF

I have no strong opinion on this, so PM to decide.

- update section classProps to more specific classNames
- update arrowStyle. Add down_right
@gqcorneby gqcorneby requested a review from tokland January 24, 2025 07:29
Copy link

@tokland tokland left a comment

Choose a reason for hiding this comment

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

Just some minor details and we're good to go.

Run yarn localize before a push, to check if there are changes on the i18n files (and the commit then, ofc). There are some changes, I think.

src/webapp/components/collapsible-section/Section.tsx Outdated Show resolved Hide resolved
src/webapp/components/collapsible-section/Section.tsx Outdated Show resolved Hide resolved
src/webapp/components/collapsible-section/Section.tsx Outdated Show resolved Hide resolved
@gqcorneby gqcorneby requested review from tokland January 27, 2025 03:55
Copy link

@tokland tokland left a comment

Choose a reason for hiding this comment

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

All good! Just added a commit for some useMemo and a comment about i18.

msgstr "<Sin valor>"
#, fuzzy
msgid "Populate"
msgstr "Plantilla"
Copy link

@tokland tokland Jan 27, 2025

Choose a reason for hiding this comment

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

We typically check fuzzy tags in PO files (gettext adds them, meaning: "I think this is the translation for a new literal I found, which is very similar to another existing, but I am not sure"). We review if correct and the remove the line "#, fuzzy".

BUT, as all the po files already contain fuzzy tags (a lot), you may leave this task to another "cleaning" PR, not in this feature. Confirm with your PM.

@@ -286,14 +285,11 @@ export const TemplateSelector = ({
const showPopulate = !(state.templateType === "custom" && !settings.showPopulateInCustomForms);
const selected = state.id && state.templateId ? getOptionValue({ id: state.id, templateId: state.templateId }) : "";

const subSectionClasses = useMemo(() => ({ sectionHeader: classes.subSectionHeader, sectionPaper: classes.subSection }), [classes]);
const subSectionClasses = { sectionHeader: classes.subSectionHeader, sectionPaper: classes.subSection };
Copy link

@tokland tokland Jan 27, 2025

Choose a reason for hiding this comment

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

[ALREADY COMMITED] But here we do need useMemo to keep it immutable, as it's an object directly passed as a prop (string, numbers, booleans, null, undefined are directly comparable, array/objects/pretty much everything else, not)

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.

3 participants