Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
presleyp merged 22 commits intomainfromlicense-banner/presleyp/3217
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
22 commits
Select commitHold shift + click to select a range
f9566ba
Extract reusable Pill component
presleypAug 17, 2022
7a6dd98
Make icon optional
presleypAug 17, 2022
0b6e336
Get pills in place
presleypAug 17, 2022
dc62449
Rough styling
presleypAug 17, 2022
5c208ce
Extract Expander component
presleypAug 18, 2022
0cf73fd
Fix alignment
presleypAug 18, 2022
3cf35aa
Put it in action - type error
presleypAug 18, 2022
c0cdf8a
Merge branch 'main' into license-banner/presleyp/3217
presleypAug 18, 2022
0aebe44
Hide banner by default
presleypAug 18, 2022
ac2b5ae
Use generated type
presleypAug 18, 2022
c55cba6
Move PaletteIndex type
presleypAug 18, 2022
77dd18b
Tweak colors
presleypAug 18, 2022
94f8b51
Format, another color tweak
presleypAug 18, 2022
69f89ef
Add stories
presleypAug 19, 2022
5d00122
Add tests
presleypAug 19, 2022
a8e6341
Update site/src/components/Pill/Pill.tsx
presleypAug 22, 2022
4d55a33
Update site/src/components/Pill/Pill.tsx
presleypAug 22, 2022
66e75bc
Comments
presleypAug 22, 2022
60e310b
Merge branch 'license-banner/presleyp/3217' of github.com:coder/coder…
presleypAug 22, 2022
95c5c2d
Remove empty story, improve empty test
presleypAug 22, 2022
62d090b
Lint
presleypAug 23, 2022
da041eb
Merge branch 'main' into license-banner/presleyp/3217
presleypAug 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletionssite/src/api/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -378,3 +378,8 @@ export const putWorkspaceExtension = async (
): Promise<void> => {
await axios.put(`/api/v2/workspaces/${workspaceId}/extend`, { deadline: newDeadline })
}

export const getEntitlements = async (): Promise<TypesGen.Entitlements> => {
const response = await axios.get("/api/v2/entitlements")
return response.data
}
2 changes: 2 additions & 0 deletionssite/src/app.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
import CssBaseline from "@material-ui/core/CssBaseline"
import ThemeProvider from "@material-ui/styles/ThemeProvider"
import { LicenseBanner } from "components/LicenseBanner/LicenseBanner"
import { FC } from "react"
import { HelmetProvider } from "react-helmet-async"
import { BrowserRouter as Router } from "react-router-dom"
Expand All@@ -18,6 +19,7 @@ export const App: FC = () => {
<CssBaseline />
<ErrorBoundary>
<XServiceProvider>
<LicenseBanner />
<AppRouter />
<GlobalSnackbar />
</XServiceProvider>
Expand Down
16 changes: 10 additions & 6 deletionssite/src/components/DropdownArrows/DropdownArrows.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,10 +3,10 @@ import KeyboardArrowDown from "@material-ui/icons/KeyboardArrowDown"
import KeyboardArrowUp from "@material-ui/icons/KeyboardArrowUp"
import { FC } from "react"

const useStyles = makeStyles((theme: Theme) => ({
const useStyles = makeStyles<Theme, ArrowProps>((theme: Theme) => ({
arrowIcon: {
color: fade(theme.palette.primary.contrastText, 0.7),
marginLeft: theme.spacing(1),
marginLeft:({ margin }) => (margin ?theme.spacing(1) : 0),
width: 16,
height: 16,
},
Expand All@@ -15,12 +15,16 @@ const useStyles = makeStyles((theme: Theme) => ({
},
}))

export const OpenDropdown: FC = () => {
const styles = useStyles()
interface ArrowProps {
margin?: boolean
}
Copy link
Member

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 themakeStyles block above:makeStyles<Theme, ArrowProps>

Copy link
Member

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 amargin prop, we add astyle prop that we spread in the children. Makes things a bit more flexible, but just a suggestion!

Copy link
ContributorAuthor

@presleyppresleypAug 22, 2022
edited
Loading

Choose a reason for hiding this comment

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

We may want to consider keepinglink text blue for accessibility reasons.

(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).

Kira-Pilot reacted with thumbs up emoji
Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

Going to wait on astyle 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.

Kira-Pilot reacted with thumbs up emoji
Copy link
Member

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.

presleyp reacted with thumbs up emoji

export const OpenDropdown: FC<ArrowProps> = ({ margin = true }) => {
const styles = useStyles({ margin })
return <KeyboardArrowDown className={styles.arrowIcon} />
}

export const CloseDropdown: FC = () => {
const styles = useStyles()
export const CloseDropdown: FC<ArrowProps> = ({ margin = true }) => {
const styles = useStyles({ margin })
return <KeyboardArrowUp className={`${styles.arrowIcon} ${styles.arrowIconUp}`} />
}
24 changes: 7 additions & 17 deletionssite/src/components/ErrorSummary/ErrorSummary.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
import Button from "@material-ui/core/Button"
import Collapse from "@material-ui/core/Collapse"
import IconButton from "@material-ui/core/IconButton"
import Link from "@material-ui/core/Link"
import { darken, lighten, makeStyles, Theme } from "@material-ui/core/styles"
import CloseIcon from "@material-ui/icons/Close"
import RefreshIcon from "@material-ui/icons/Refresh"
import { ApiError, getErrorDetail, getErrorMessage } from "api/errors"
import { Expander } from "components/Expander/Expander"
import { Stack } from "components/Stack/Stack"
import { FC, useState } from "react"

Expand DownExpand Up@@ -36,10 +36,6 @@ export const ErrorSummary: FC<React.PropsWithChildren<ErrorSummaryProps>> = ({

const styles = useStyles({ showDetails })

const toggleShowDetails = () => {
setShowDetails(!showDetails)
}

const closeError = () => {
setOpen(false)
}
Expand All@@ -51,19 +47,10 @@ export const ErrorSummary: FC<React.PropsWithChildren<ErrorSummaryProps>> = ({
return (
<Stack className={styles.root}>
<Stack direction="row" alignItems="center" className={styles.messageBox}>
<div>
<Stack direction="row" spacing={0}>
<span className={styles.errorMessage}>{message}</span>
{!!detail && (
<Link
aria-expanded={showDetails}
onClick={toggleShowDetails}
className={styles.detailsLink}
tabIndex={0}
>
{showDetails ? Language.lessDetails : Language.moreDetails}
</Link>
)}
</div>
{!!detail && <Expander expanded={showDetails} setExpanded={setShowDetails} />}
</Stack>
{dismissible && (
<IconButton onClick={closeError} className={styles.iconButton}>
<CloseIcon className={styles.closeIcon} />
Expand DownExpand Up@@ -101,6 +88,9 @@ const useStyles = makeStyles<Theme, StyleProps>((theme) => ({
borderRadius: theme.shape.borderRadius,
gap: 0,
},
flex: {
display: "flex",
},
messageBox: {
justifyContent: "space-between",
},
Expand Down
22 changes: 22 additions & 0 deletionssite/src/components/Expander/Expander.stories.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff 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,
}
45 changes: 45 additions & 0 deletionssite/src/components/Expander/Expander.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff 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",
},
}))
27 changes: 27 additions & 0 deletionssite/src/components/LicenseBanner/LicenseBanner.test.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff 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()
})
})
21 changes: 21 additions & 0 deletionssite/src/components/LicenseBanner/LicenseBanner.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff 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
}
}
View file
Open in desktop
Original file line numberDiff line numberDiff 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.",
],
}
87 changes: 87 additions & 0 deletionssite/src/components/LicenseBanner/LicenseBannerView.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff 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>
&nbsp;
<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>
&nbsp;
<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),
},
}))
Loading

[8]ページ先頭

©2009-2025 Movatter.jp