-
Notifications
You must be signed in to change notification settings - Fork 905
feat: Add LicenseBanner #3568
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
Merged
feat: Add LicenseBanner #3568
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
f9566ba
Extract reusable Pill component
presleyp 7a6dd98
Make icon optional
presleyp 0b6e336
Get pills in place
presleyp dc62449
Rough styling
presleyp 5c208ce
Extract Expander component
presleyp 0cf73fd
Fix alignment
presleyp 3cf35aa
Put it in action - type error
presleyp c0cdf8a
Merge branch 'main' into license-banner/presleyp/3217
presleyp 0aebe44
Hide banner by default
presleyp ac2b5ae
Use generated type
presleyp c55cba6
Move PaletteIndex type
presleyp 77dd18b
Tweak colors
presleyp 94f8b51
Format, another color tweak
presleyp 69f89ef
Add stories
presleyp 5d00122
Add tests
presleyp a8e6341
Update site/src/components/Pill/Pill.tsx
presleyp 4d55a33
Update site/src/components/Pill/Pill.tsx
presleyp 66e75bc
Comments
presleyp 60e310b
Merge branch 'license-banner/presleyp/3217' of github.com:coder/coder…
presleyp 95c5c2d
Remove empty story, improve empty test
presleyp 62d090b
Lint
presleyp da041eb
Merge branch 'main' into license-banner/presleyp/3217
presleyp 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
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
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
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
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,22 @@ | ||
import { Story } from "@storybook/react" | ||
import { Expander, ExpanderProps } from "./Expander" | ||
|
||
export default { | ||
title: "components/Expander", | ||
component: Expander, | ||
argTypes: { | ||
setExpanded: { action: "setExpanded" }, | ||
}, | ||
} | ||
|
||
const Template: Story<ExpanderProps> = (args) => <Expander {...args} /> | ||
|
||
export const Expanded = Template.bind({}) | ||
Expanded.args = { | ||
expanded: true, | ||
} | ||
|
||
export const Collapsed = Template.bind({}) | ||
Collapsed.args = { | ||
expanded: false, | ||
} |
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,45 @@ | ||
import Link from "@material-ui/core/Link" | ||
import makeStyles from "@material-ui/core/styles/makeStyles" | ||
import { CloseDropdown, OpenDropdown } from "components/DropdownArrows/DropdownArrows" | ||
|
||
const Language = { | ||
expand: "More", | ||
collapse: "Less", | ||
} | ||
|
||
export interface ExpanderProps { | ||
expanded: boolean | ||
setExpanded: (val: boolean) => void | ||
} | ||
|
||
export const Expander: React.FC<ExpanderProps> = ({ expanded, setExpanded }) => { | ||
const toggleExpanded = () => setExpanded(!expanded) | ||
const styles = useStyles() | ||
return ( | ||
<Link aria-expanded={expanded} onClick={toggleExpanded} className={styles.expandLink}> | ||
{expanded ? ( | ||
<span className={styles.text}> | ||
{Language.collapse} | ||
<CloseDropdown margin={false} />{" "} | ||
</span> | ||
) : ( | ||
<span className={styles.text}> | ||
{Language.expand} | ||
<OpenDropdown margin={false} /> | ||
</span> | ||
)} | ||
</Link> | ||
) | ||
} | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
expandLink: { | ||
cursor: "pointer", | ||
color: theme.palette.text.primary, | ||
display: "flex", | ||
}, | ||
text: { | ||
display: "flex", | ||
alignItems: "center", | ||
}, | ||
})) |
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,27 @@ | ||
import { screen } from "@testing-library/react" | ||
import { rest } from "msw" | ||
import { MockEntitlementsWithWarnings } from "testHelpers/entities" | ||
import { render } from "testHelpers/renderHelpers" | ||
import { server } from "testHelpers/server" | ||
import { LicenseBanner } from "./LicenseBanner" | ||
import { Language } from "./LicenseBannerView" | ||
|
||
describe("LicenseBanner", () => { | ||
it("does not show when there are no warnings", async () => { | ||
render(<LicenseBanner />) | ||
const bannerPillSingular = await screen.queryByText(Language.licenseIssue) | ||
const bannerPillPlural = await screen.queryByText(Language.licenseIssues(2)) | ||
expect(bannerPillSingular).toBe(null) | ||
expect(bannerPillPlural).toBe(null) | ||
}) | ||
it("shows when there are warnings", async () => { | ||
server.use( | ||
rest.get("/api/v2/entitlements", (req, res, ctx) => { | ||
return res(ctx.status(200), ctx.json(MockEntitlementsWithWarnings)) | ||
}), | ||
) | ||
render(<LicenseBanner />) | ||
const bannerPill = await screen.findByText(Language.licenseIssues(2)) | ||
expect(bannerPill).toBeDefined() | ||
}) | ||
}) |
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,21 @@ | ||
import { useActor } from "@xstate/react" | ||
import { useContext, useEffect } from "react" | ||
import { XServiceContext } from "xServices/StateContext" | ||
import { LicenseBannerView } from "./LicenseBannerView" | ||
|
||
export const LicenseBanner: React.FC = () => { | ||
const xServices = useContext(XServiceContext) | ||
const [entitlementsState, entitlementsSend] = useActor(xServices.entitlementsXService) | ||
const { warnings } = entitlementsState.context.entitlements | ||
|
||
/** Gets license data on app mount because LicenseBanner is mounted in App */ | ||
useEffect(() => { | ||
entitlementsSend("GET_ENTITLEMENTS") | ||
}, [entitlementsSend]) | ||
|
||
if (warnings.length) { | ||
return <LicenseBannerView warnings={warnings} /> | ||
} else { | ||
return null | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
site/src/components/LicenseBanner/LicenseBannerView.stories.tsx
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,22 @@ | ||
import { Story } from "@storybook/react" | ||
import { LicenseBannerView, LicenseBannerViewProps } from "./LicenseBannerView" | ||
|
||
export default { | ||
title: "components/LicenseBannerView", | ||
component: LicenseBannerView, | ||
} | ||
|
||
const Template: Story<LicenseBannerViewProps> = (args) => <LicenseBannerView {...args} /> | ||
|
||
export const OneWarning = Template.bind({}) | ||
OneWarning.args = { | ||
warnings: ["You have exceeded the number of seats in your license."], | ||
} | ||
|
||
export const TwoWarnings = Template.bind({}) | ||
TwoWarnings.args = { | ||
warnings: [ | ||
"You have exceeded the number of seats in your license.", | ||
"You are flying too close to the sun.", | ||
], | ||
} |
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,87 @@ | ||
import Collapse from "@material-ui/core/Collapse" | ||
import { makeStyles } from "@material-ui/core/styles" | ||
import { Expander } from "components/Expander/Expander" | ||
import { Pill } from "components/Pill/Pill" | ||
import { useState } from "react" | ||
|
||
export const Language = { | ||
licenseIssue: "License Issue", | ||
licenseIssues: (num: number): string => `${num} License Issues`, | ||
upgrade: "Contact us to upgrade your license.", | ||
exceeded: "It looks like you've exceeded some limits of your license.", | ||
lessDetails: "Less", | ||
moreDetails: "More", | ||
} | ||
|
||
export interface LicenseBannerViewProps { | ||
warnings: string[] | ||
} | ||
|
||
export const LicenseBannerView: React.FC<LicenseBannerViewProps> = ({ warnings }) => { | ||
const styles = useStyles() | ||
const [showDetails, setShowDetails] = useState(false) | ||
if (warnings.length === 1) { | ||
return ( | ||
<div className={styles.container}> | ||
<Pill text={Language.licenseIssue} type="warning" lightBorder /> | ||
<span className={styles.text}>{warnings[0]}</span> | ||
| ||
<a href="mailto:sales@coder.com" className={styles.link}> | ||
{Language.upgrade} | ||
</a> | ||
</div> | ||
) | ||
} else { | ||
return ( | ||
<div className={styles.container}> | ||
<div className={styles.flex}> | ||
<div className={styles.leftContent}> | ||
<Pill text={Language.licenseIssues(warnings.length)} type="warning" lightBorder /> | ||
<span className={styles.text}>{Language.exceeded}</span> | ||
| ||
<a href="mailto:sales@coder.com" className={styles.link}> | ||
{Language.upgrade} | ||
</a> | ||
</div> | ||
<Expander expanded={showDetails} setExpanded={setShowDetails} /> | ||
</div> | ||
<Collapse in={showDetails}> | ||
<ul className={styles.list}> | ||
{warnings.map((warning) => ( | ||
<li className={styles.listItem} key={`${warning}`}> | ||
{warning} | ||
</li> | ||
))} | ||
</ul> | ||
</Collapse> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
container: { | ||
padding: theme.spacing(1.5), | ||
backgroundColor: theme.palette.warning.main, | ||
}, | ||
flex: { | ||
display: "flex", | ||
}, | ||
leftContent: { | ||
marginRight: theme.spacing(1), | ||
}, | ||
text: { | ||
marginLeft: theme.spacing(1), | ||
}, | ||
link: { | ||
color: "inherit", | ||
textDecoration: "none", | ||
fontWeight: "bold", | ||
}, | ||
list: { | ||
margin: theme.spacing(1.5), | ||
}, | ||
listItem: { | ||
margin: theme.spacing(1), | ||
}, | ||
})) |
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.
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 could share this typing with the
makeStyles
block above:makeStyles<Theme, ArrowProps>
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 also wonder if, instead of a
margin
prop, we add astyle
prop that we spread in the children. Makes things a bit more flexible, but just a suggestion!Uh oh!
There was an error while loading. Please reload this page.
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 comment ended up in the wrong place, sorry for the confusion!)
@Kira-Pilot Yeah, so I changed this because I thought the color combination was bad and it was also going to pose a contrast issue, but I have been wondering if it's obvious enough. I think the chevron and placement helps. But I also think I'm having trouble making it blue or underlined because it's a not a navigation link. It's really a button in functionality. What do you think is the best way to style that? I guess Zenhub styles "Show 4 more" on this page like a link (bold and blue).
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.
Going to wait on a
style
prop here because I think this component will be revisited in future color work and it'll be easier to tell then what to do.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.
@presleyp That makes sense! I agree with your logic and I don't think it's something we need to change right now. Let's keep it back of mind and look out for link inspo in the future.