-
Notifications
You must be signed in to change notification settings - Fork 9
[OSDEV-2375] Create location name, OS ID, and "Understanding Data Sources" sections #893
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
Merged
VadimKovalenkoSNF
merged 38 commits into
main
from
OSDEV-2375-location-name-os-id-understanging-data-source
Mar 3, 2026
Merged
Changes from 27 commits
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
eeca1f1
Add basic classes for ClaimFlag (partial impl)
VadimKovalenkoSNF c83b677
Optimize class assigment
VadimKovalenkoSNF fb4d282
Minor style refactoring
VadimKovalenkoSNF b32a24c
Dialog tooltip optimization
VadimKovalenkoSNF b738170
Pass embed config flag (secure measure)
VadimKovalenkoSNF ee87028
Clear timeout for TooltipDialog popup
VadimKovalenkoSNF 6304eab
Clear timeout for DialogTooltip popup, adjust user accessibility
VadimKovalenkoSNF 5e3984d
Connect closure status badge
VadimKovalenkoSNF e2a475e
Guard React.cloneElement against non-element children in interactive …
VadimKovalenkoSNF af374f6
Add unit tests
VadimKovalenkoSNF 1b60b17
Fix lint issues
VadimKovalenkoSNF e07a9ed
Add proptypes to the closure report component, fix minor issues
VadimKovalenkoSNF 5be8398
Fix unit test
VadimKovalenkoSNF a8ddc91
Merge branch 'main' into OSDEV-2374-implement-claim-banner-with-statu…
VadimKovalenkoSNF 3234ffe
Merge branch 'main' into OSDEV-2374-implement-claim-banner-with-statu…
VadimKovalenkoSNF 31761c9
Fix post-merge errors
VadimKovalenkoSNF 249ba92
Refactor DialogTooltip to pass href as a separate component
VadimKovalenkoSNF ee7fda9
Refactor DialogTooltip keyboard navigation
VadimKovalenkoSNF bfc273e
Refactor ClaimFlag util functions
VadimKovalenkoSNF 84f9d9b
Split ClaimFlag into smaller inner components
VadimKovalenkoSNF 5ecf343
Fix lint issues
VadimKovalenkoSNF a630082
Add os id and data source section (partial impl)
VadimKovalenkoSNF 43a4655
Adjust styles, add tooltip and toogle switch
VadimKovalenkoSNF 4fd3cce
Align styles across components (partial impl)
VadimKovalenkoSNF 173413a
Create frontend.md docs
VadimKovalenkoSNF ed9e9b4
Minor style fix, update tooltip text
VadimKovalenkoSNF 89610eb
Merge branch 'main' into OSDEV-2375-location-name-os-id-understanging…
VadimKovalenkoSNF a111202
Fix lint issue
VadimKovalenkoSNF e080926
Update styles and layout, use rem units for body fonts
VadimKovalenkoSNF 6aa0e18
Merge branch 'main' into OSDEV-2375-location-name-os-id-understanging…
VadimKovalenkoSNF 84ba6ab
Add unit tests
VadimKovalenkoSNF 11c9a02
Coercing embed to a boolean when passing it to ProductionLocationDeta…
VadimKovalenkoSNF 154aa72
interactive attr is no longer set to MUI’s Tooltip
VadimKovalenkoSNF 544ee14
Apply set of minor html fixes
VadimKovalenkoSNF df43954
Fix lint issues
VadimKovalenkoSNF bc34dc9
Fix icon data source section on small devices
VadimKovalenkoSNF 52ff8ef
Update colors for the data source section
VadimKovalenkoSNF e1e90a3
Update release notes
VadimKovalenkoSNF File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| # Typography Guide | ||
|
|
||
| How to use typography across the application: which shared styles to use, how to combine them with MUI `Typography`, and when to use each. | ||
|
|
||
| --- | ||
|
|
||
| ## 1. Source of truth | ||
|
|
||
| - **File:** `src/react/src/util/typographyStyles.js` | ||
| - **Usage:** Call `getTypographyStyles(theme)` in your component's `withStyles` (or `makeStyles`) and spread the returned keys into your class objects; then pass those classes to MUI `Typography` via `className={classes.xyz}`. | ||
| - **Rule:** Prefer these tokens over hardcoding font sizes/weights so headings, labels, body text, and links stay consistent. | ||
|
|
||
| --- | ||
|
|
||
| ## 2. Semantic roles and which style to use | ||
|
|
||
| | Role | When to use | Style key | Typical MUI usage | | ||
| |------|-------------|-----------|-------------------| | ||
| | **Page title** | Main title of a page (e.g. facility/location name) | (custom from `formLabelTight`) | `<Typography component="h1" variant="h1" className={classes.title} />` | | ||
| | **Major section** | Big section blocks (e.g. claim intro) | (custom as needed) | `component="h2"`, `variant="h2"` | | ||
| | **Section title** | Subsections ("Understanding Data Sources", "Partner Data", etc.) | `sectionTitle` | `component="h3"`, `variant="h3"`, `className` with `...typography.sectionTitle` | | ||
| | **Field / UI label** | Form labels, bold labels ("OS ID:", "CLAIMED PROFILE", "Claimed", "Crowdsourced") | `formLabel` or `formLabelTight` | `component="span"` or `"label"`, `variant="body1"`, `className` with `...typography.formLabelTight` | | ||
| | **Body / paragraph** | Normal paragraphs, descriptions, "Show more" labels | `bodyText` | `component="p"` or `"span"`, `variant="body1"`, `className` with `...typography.bodyText` | | ||
| | **Section description** | Intro or explanatory block under a section | `sectionDescription` | `component="p"`, `variant="body1"`, `className` with `...typography.sectionDescription` | | ||
| | **Inline highlight** | Short emphasized bits (name, date, ID value) inline in text | `inlineHighlight` | `component="span"`, `className` with `...typography.inlineHighlight` | | ||
|
|
||
| --- | ||
|
|
||
| ## 3. Style attributes (from `typographyStyles.js`) | ||
|
|
||
| - **formLabel / formLabelRoot / formLabelTight** | ||
| Base: `fontSize: '21px'`, `fontWeight: 600`. | ||
| `formLabel` adds `margin: '24px 0 8px 0'`; `formLabelRoot` uses `marginTop: 0`, `marginBottom: '8px'`; `formLabelTight` has no extra margin. | ||
| Use for field labels and strong short labels. | ||
|
|
||
| - **sectionTitle** | ||
| `fontSize: '24px'`, `fontWeight: theme.typography.fontWeightSemiBold`, `marginTop: '25px'`. | ||
| Use for h3-level section titles. | ||
|
|
||
| - **sectionDescription** | ||
| `fontSize: '18px'`, `marginBottom: '10px'`. | ||
| Use for the first paragraph or intro under a section. | ||
|
|
||
| - **bodyText** | ||
| `fontSize: '18px'`, `color: theme.palette.text.secondary`. | ||
| Use for regular body and secondary text. | ||
|
|
||
| - **inlineHighlight** | ||
| `fontWeight: 500`, `color: theme.palette.text.primary`, `display: 'inline'`. | ||
| Use for emphasized inline pieces (e.g. facility name, date, OS ID value). | ||
|
|
||
| --- | ||
|
|
||
| ## 4. Headings | ||
|
|
||
| - **h1 – Page title** | ||
| One per page (e.g. facility/location name). | ||
| Example: `component="h1"`, `variant="h1"`, `className` from styles that extend `formLabelTight` (e.g. 28px, 700 for prominence). | ||
|
|
||
| - **h2 – Major section** | ||
| Top-level sections (e.g. claim intro). | ||
| `component="h2"`, `variant="h2"`, plus custom class if needed. | ||
|
|
||
| - **h3 – Section title** | ||
| Subsections ("Understanding Data Sources", "Partner Data", "Interactive map", etc.). | ||
| `component="h3"`, `variant="h3"`, `className` with `...typography.sectionTitle` (and margin overrides as needed, e.g. `marginTop: 0`). | ||
|
|
||
| - **h4 / h5 / h6** | ||
| Use sparingly for sub-subsections (e.g. ClaimFlag uses `h4` for "CLAIMED PROFILE"). | ||
| Prefer a class that extends `formLabelTight` or `sectionTitle` so sizing stays consistent. | ||
|
|
||
| --- | ||
|
|
||
| ## 5. Regular text | ||
|
|
||
| - **Paragraphs:** | ||
| `component="p"`, `variant="body1"`, and a class that includes `...typography.bodyText` (and optionally `...typography.sectionDescription` for intro blocks). | ||
| Override `fontSize` or `marginBottom` only when needed (e.g. 16px for subsection text). | ||
|
|
||
| - **Inline text / labels:** | ||
| `component="span"`, `variant="body1"`, and either `formLabelTight` (labels) or `bodyText` (secondary inline). | ||
|
|
||
| --- | ||
|
|
||
| ## 6. Links | ||
|
|
||
| - **Color:** `theme.palette.primary.main`. | ||
| - **Implementation:** | ||
| Use `<a href="..." className={classes.link}>` or `<Link to="..." className={classes.link}>` with a style like `link: { color: theme.palette.primary.main }`. | ||
| For "Learn more →" in tooltips, inline `style={{ color: 'white' }}` is used for contrast on dark tooltip background; elsewhere use the theme primary color. | ||
| - **Optional:** Add `textDecoration: 'none'` and `'&:hover': { textDecoration: 'underline' }` for inline links (e.g. in DataSourcesInfo `learnMoreLink`). | ||
|
|
||
| --- | ||
|
|
||
| ## 7. Usage pattern | ||
|
|
||
| 1. In the component's `styles.js`: | ||
| `import { getTypographyStyles } from '../../path/to/typographyStyles';` | ||
| then `const typography = getTypographyStyles(theme);` and use `...typography.sectionTitle`, etc., in your class objects. | ||
|
|
||
| 2. In the JSX: | ||
| Use MUI `Typography` with both: | ||
| - **Semantic props:** `component` and `variant` (e.g. `component="h3"`, `variant="h3"` for section titles). | ||
| - **Visual style:** `className={classes.yourClass}` where `yourClass` spreads the right typography token and any local overrides. | ||
|
|
||
| 3. Keep **one** clear hierarchy per page: one h1, then h2/h3 as needed; use the table in §2 to pick the right style key and component/variant. | ||
|
|
||
| --- | ||
|
|
||
| ## 8. Quick reference | ||
|
|
||
| | Use case | component | variant | Typography style key | | ||
| |----------|-----------|--------|----------------------| | ||
| | Page title (e.g. facility name) | h1 | h1 | formLabelTight (custom size/weight) | | ||
| | Section title | h3 | h3 | sectionTitle | | ||
| | Field / subsection label | span | body1 | formLabelTight | | ||
| | Paragraph / body | p | body1 | bodyText or sectionDescription | | ||
| | Inline emphasis (name, ID, date) | span | — | inlineHighlight | | ||
| | Links | a or Link | — | color: theme.palette.primary.main | | ||
|
|
||
| --- | ||
|
|
||
| ## 9. Container styles (commonStyles) | ||
|
|
||
| - **File:** `src/react/src/components/ProductionLocation/commonStyles.js` | ||
| - **Purpose:** Shared base styles for section containers (e.g. cards, content blocks) so background and shadow stay consistent across the Production Location UI. | ||
|
|
||
| ### What it provides | ||
|
|
||
| `commonStyles(theme)` returns an object with a `container` key: | ||
|
|
||
| - **container:** `backgroundColor: theme.palette.background.white`, `boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1)'` | ||
|
|
||
| ### How to use it | ||
|
|
||
| Spread `commonStyles(theme).container` into your own container class and add any overrides (margin, padding, etc.). This keeps the same background and shadow while letting each component set its own spacing. | ||
|
|
||
| **Import in your styles file:** | ||
|
|
||
| ```js | ||
| import commonStyles from '../../commonStyles'; // adjust path to your component | ||
| ``` | ||
|
|
||
| **Example – extend and override:** | ||
|
|
||
| ```js | ||
| container: Object.freeze({ | ||
| ...commonStyles(theme).container, | ||
| marginBottom: spacing * 3, | ||
| padding: '20px 20px 20px 36px', | ||
| }), | ||
| ``` | ||
|
|
||
| Here the container gets the shared `backgroundColor` and `boxShadow` from `commonStyles`, plus component-specific `marginBottom` and `padding`. Use this pattern for any Production Location section that should look like a card (e.g. LocationTitle, DataSourcesInfo). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/react/src/components/ProductionLocation/Heading/DataSourcesInfo/DataSourceItem.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| import React from 'react'; | ||
| import PropTypes from 'prop-types'; | ||
| import Grid from '@material-ui/core/Grid'; | ||
| import Typography from '@material-ui/core/Typography'; | ||
|
|
||
| const DataSourceItem = ({ | ||
| classes, | ||
| Icon, | ||
| iconClassName, | ||
| title, | ||
| subsectionText, | ||
| showSubsectionInfo, | ||
| showLearnMore, | ||
| learnMoreUrl, | ||
| }) => ( | ||
| <Grid item sm={12} md={4} className={classes.descriptionItem}> | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| <div className={classes.itemContent}> | ||
| <Icon className={iconClassName} aria-hidden /> | ||
| <div className={classes.itemText}> | ||
| <Typography | ||
| component="span" | ||
| className={classes.label} | ||
| variant="body1" | ||
| > | ||
| {title} | ||
| </Typography> | ||
| {showSubsectionInfo && ( | ||
| <Typography | ||
| component="p" | ||
| variant="body1" | ||
| className={classes.subsectionText} | ||
| > | ||
| {subsectionText} | ||
| {showLearnMore && learnMoreUrl && ( | ||
| <> | ||
| {' '} | ||
| <a | ||
| href={learnMoreUrl} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className={classes.learnMoreLink} | ||
| > | ||
| Learn more → | ||
| </a> | ||
| </> | ||
| )} | ||
| </Typography> | ||
| )} | ||
| </div> | ||
| </div> | ||
| </Grid> | ||
| ); | ||
|
|
||
| DataSourceItem.propTypes = { | ||
| classes: PropTypes.object.isRequired, | ||
| Icon: PropTypes.func.isRequired, | ||
| iconClassName: PropTypes.string.isRequired, | ||
| title: PropTypes.string.isRequired, | ||
| subsectionText: PropTypes.string.isRequired, | ||
| showSubsectionInfo: PropTypes.bool.isRequired, | ||
| showLearnMore: PropTypes.bool, | ||
| learnMoreUrl: PropTypes.string, | ||
| }; | ||
|
|
||
| DataSourceItem.defaultProps = { | ||
| showLearnMore: false, | ||
| learnMoreUrl: null, | ||
| }; | ||
|
|
||
| export default DataSourceItem; | ||
101 changes: 93 additions & 8 deletions
101
src/react/src/components/ProductionLocation/Heading/DataSourcesInfo/DataSourcesInfo.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
src/react/src/components/ProductionLocation/Heading/DataSourcesInfo/constants.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; | ||
| import People from '@material-ui/icons/People'; | ||
| import GroupWork from '@material-ui/icons/GroupWork'; | ||
|
|
||
| export const DATA_SOURCES_TOOLTIP_TEXT = | ||
| 'Open Supply Hub is collaboratively mapping global supply chains. This model means that data comes into the platform in a few ways.'; | ||
| export const DATA_SOURCES_LEARN_MORE_URL = | ||
| 'https://info.opensupplyhub.org/resources/an-open-data-model'; | ||
|
|
||
| export const DATA_SOURCES_ITEMS = Object.freeze([ | ||
| Object.freeze({ | ||
| Icon: CheckCircleOutline, | ||
| iconClassNameKey: 'iconClaimed', | ||
| title: 'Claimed', | ||
| subsectionText: | ||
| 'General information & operational details submitted by production location', | ||
| }), | ||
| Object.freeze({ | ||
| Icon: People, | ||
| iconClassNameKey: 'iconCrowdsourced', | ||
| title: 'Crowdsourced', | ||
| subsectionText: | ||
| "General information shared by supply chain stakeholders & OS Hub's research team", | ||
| showLearnMore: true, | ||
| }), | ||
| Object.freeze({ | ||
| Icon: GroupWork, | ||
| iconClassNameKey: 'iconPartner', | ||
| title: 'Partner Data', | ||
| subsectionText: | ||
| 'Additional social or environmental information shared by third party platforms', | ||
| showLearnMore: true, | ||
| }), | ||
| ]); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.