Skip to content

Commit 559f732

Browse files
committed
feat: add about devtron info modal
1 parent 9a7f7c9 commit 559f732

19 files changed

+197
-381
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { ClipboardButton } from '@Common/index'
2+
import { ReactComponent as ICChatSupport } from '@IconsV2/ic-chat-circle-dots.svg'
3+
import { DevtronLicenseCardProps, LicenseStatus } from '@Shared/index'
4+
import { Button, ButtonVariantType } from '../Button'
5+
import { Icon } from '../Icon'
6+
import { getLicenseColorsAccordingToStatus, getTTLInHumanReadableFormat } from './utils'
7+
import './licenseCard.scss'
8+
9+
export const DevtronLicenseCard = ({
10+
enterpriseName,
11+
licenseKey,
12+
licenseSuffix,
13+
expiryDate,
14+
licenseStatus,
15+
isTrial,
16+
ttl,
17+
}: DevtronLicenseCardProps) => {
18+
const { bgColor, textColor } = getLicenseColorsAccordingToStatus(licenseStatus)
19+
const remainingTime = getTTLInHumanReadableFormat(Math.abs(ttl))
20+
const remainingTimeString = ttl < 0 ? `Expired ${remainingTime} ago` : `${remainingTime} remaining`
21+
22+
return (
23+
<div className="flexbox-col p-8 br-16" style={{ backgroundColor: bgColor }}>
24+
<div className="license-card flexbox-col br-12 h-200 bg__tertiary">
25+
<div className="p-20 flexbox-col dc__content-space flex-grow-1">
26+
<div className="flexbox dc__align-items-center dc__content-space">
27+
<span className="font-merriweather cn-9 fs-16 fw-7 lh-1-5">{enterpriseName}</span>
28+
<Icon name="ic-devtron" color="N900" size={24} />
29+
</div>
30+
<div className="flexbox-col dc__gap-4">
31+
<div className="flexbox dc__align-items-center dc__gap-6">
32+
<Icon name="ic-key" color={null} size={20} />
33+
<div className="flex dc__gap-4 cn-7 fs-16 fw-5 lh-1-5 font-ibm-plex-mono">
34+
<span>••••</span>
35+
<span>{licenseSuffix || licenseKey?.slice(-8)}</span>
36+
</div>
37+
{licenseKey && <ClipboardButton content={licenseKey} />}
38+
</div>
39+
<div className="flexbox dc__align-items-center dc__gap-4">
40+
<span>{expiryDate}</span>
41+
<span></span>
42+
<span style={{ color: textColor }}>{remainingTimeString}</span>
43+
</div>
44+
</div>
45+
</div>
46+
{isTrial && (
47+
<span className="trial-license-badge flexbox dc__align-items-center px-20 py-6 cn-9 fs-11 fw-5 lh-1-5">
48+
TRIAL LICENSE
49+
</span>
50+
)}
51+
</div>
52+
{licenseStatus !== LicenseStatus.ACTIVE && (
53+
<div className="p-16 flexbox-col dc__gap-8">
54+
<div className="flexbox dc__gap-8">
55+
<span>
56+
{/* TODO: Confirm with product team */}
57+
To renew your license mail us at enterprise@devtron.ai or contact your Devtron
58+
representative.
59+
</span>
60+
<Icon name="ic-timer" color="Y500" size={16} />
61+
</div>
62+
<Button
63+
dataTestId="contact-support"
64+
startIcon={<ICChatSupport />}
65+
text="Contact support"
66+
variant={ButtonVariantType.text}
67+
/>
68+
</div>
69+
)}
70+
</div>
71+
)
72+
}
73+
74+
export default DevtronLicenseCard
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as DevtronLicenseCard } from './DevtronLicenseCard'
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.license-card {
2+
border: 1px solid var(--border-secondary-translucent, rgba(255, 255, 255, 0.1));
3+
background: radial-gradient(340.2% 100% at 0% 0%, var(--bg-primary, #0f0f10) 0%, var(--bg-tertiary, #030303) 100%);
4+
box-shadow:
5+
0px 1px 1px 0px rgba(0, 0, 0, 0.04),
6+
0px 2px 6px 0px rgba(0, 0, 0, 0.04),
7+
0px 4px 12px 0px rgba(0, 0, 0, 0.1);
8+
9+
.trial-license-badge {
10+
background-color: var(--bg-hover);
11+
letter-spacing: 0.55px;
12+
border-bottom-left-radius: 12px;
13+
border-bottom-right-radius: 12px;
14+
}
15+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { LicenseStatus } from '@Shared/index'
2+
import moment from 'moment'
3+
4+
export const getLicenseColorsAccordingToStatus = (
5+
licenseStatus: LicenseStatus,
6+
): { bgColor: string; textColor: string } => {
7+
switch (licenseStatus) {
8+
case LicenseStatus.ACTIVE:
9+
return { bgColor: 'var(--G100)', textColor: 'var(--G500)' }
10+
case LicenseStatus.REMINDER_THRESHOLD_REACHED:
11+
return { bgColor: 'var(--Y100)', textColor: 'var(--Y700)' }
12+
default:
13+
return { bgColor: 'var(--R100)', textColor: 'var(--R500)' }
14+
}
15+
}
16+
17+
export const getTTLInHumanReadableFormat = (ttl: number): string => {
18+
const duration = moment.duration(ttl, 'seconds')
19+
20+
if (duration.asYears() >= 1) {
21+
const years = Math.floor(duration.asYears())
22+
const months = duration.months()
23+
if (months > 0) {
24+
return `${years} ${years > 1 ? 'years' : 'year'}, ${months} ${months > 1 ? 'months' : 'month'}`
25+
}
26+
return `${years} ${years > 1 ? 'years' : 'year'}`
27+
}
28+
29+
if (duration.asMonths() >= 1) {
30+
const months = Math.floor(duration.asMonths())
31+
return `${months} ${months > 1 ? 'months' : 'month'}`
32+
}
33+
34+
if (duration.asDays() >= 1) {
35+
const days = Math.floor(duration.asDays())
36+
return `${days} ${days > 1 ? 'days' : 'day'}`
37+
}
38+
39+
if (duration.asHours() >= 1) {
40+
const hours = Math.floor(duration.asHours())
41+
return `${hours} ${hours > 1 ? 'hours' : 'hour'}`
42+
}
43+
44+
const minutes = Math.floor(duration.asMinutes())
45+
return `${minutes} ${minutes > 1 ? 'minutes' : 'minute'}`
46+
}

src/Shared/Components/Header/HelpNav.tsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { ReactComponent as Feedback } from '../../../Assets/Icon/ic-feedback.svg
2626
import { ReactComponent as Discord } from '../../../Assets/Icon/ic-discord-fill.svg'
2727
import { ReactComponent as File } from '../../../Assets/Icon/ic-file-text.svg'
2828
import { useMainContext } from '../../Providers'
29+
import { Icon } from '../Icon'
2930

3031
const HelpNav = ({
3132
className,
@@ -34,6 +35,7 @@ const HelpNav = ({
3435
fetchingServerInfo,
3536
setGettingStartedClicked,
3637
showHelpCard,
38+
openAboutDevtronDialog,
3739
}: HelpNavType) => {
3840
const { currentServerInfo } = useMainContext()
3941
const isEnterprise = currentServerInfo?.serverInfo?.installationType === InstallationType.ENTERPRISE
@@ -44,14 +46,12 @@ const HelpNav = ({
4446
name: 'View documentation',
4547
link: DOCUMENTATION_HOME_PAGE,
4648
icon: File,
47-
showSeparator: true,
4849
},
4950

5051
{
5152
name: 'Join discord community',
5253
link: DISCORD_LINK,
5354
icon: Discord,
54-
showSeparator: isEnterprise,
5555
},
5656
...(isEnterprise ? EnterpriseHelpOptions : OSSHelpOptions),
5757
]
@@ -75,7 +75,7 @@ const HelpNav = ({
7575
<div onClick={stopPropagation} className="help-card__option help-card__link flex left cn-9">
7676
<Feedback />
7777
<SliderButton
78-
className="dc__transparent help-card__option-name ml-12 cn-9 fs-14"
78+
className="dc__transparent ml-12 cn-9 fs-14"
7979
id={FEEDBACK_FORM_ID}
8080
onClose={toggleHelpCard}
8181
autoClose={2000}
@@ -92,7 +92,6 @@ const HelpNav = ({
9292

9393
const renderHelpOptions = (): JSX.Element => (
9494
<>
95-
{' '}
9695
{CommonHelpOptions.map((option, index) => (
9796
<Fragment key={option.name}>
9897
<a
@@ -105,12 +104,23 @@ const HelpNav = ({
105104
onClick={handleHelpOptions}
106105
>
107106
<option.icon />
108-
<div className="help-card__option-name ml-12 cn-9 fs-14">{option.name}</div>
107+
<div className="ml-12 cn-9 fs-14">{option.name}</div>
109108
</a>
110109
{isEnterprise && index === 1 && (
111-
<div className="help__enterprise pl-8 pb-4-imp pt-4-imp dc__gap-12 flexbox dc__align-items-center h-28">
112-
Enterprise Support
113-
</div>
110+
<>
111+
<div
112+
role="button"
113+
tabIndex={0}
114+
className="help-card__option flexbox dc__align-items-center cn-9 dc__gap-12 fs-14"
115+
onClick={openAboutDevtronDialog}
116+
>
117+
<Icon name="ic-devtron" color="N600" size={20} />
118+
About Devtron
119+
</div>
120+
<div className="help__enterprise pl-8 pb-4-imp pt-4-imp dc__gap-12 flexbox dc__align-items-center h-28">
121+
Enterprise Support
122+
</div>
123+
</>
114124
)}
115125
</Fragment>
116126
))}
@@ -128,7 +138,7 @@ const HelpNav = ({
128138
onClick={onClickGettingStarted}
129139
>
130140
<GettingStartedIcon className="scn-6" />
131-
<div className="help-card__option-name ml-12 cn-9 fs-14" data-testid="getting-started-link">
141+
<div className="ml-12 cn-9 fs-14" data-testid="getting-started-link">
132142
Getting started
133143
</div>
134144
</NavLink>

src/Shared/Components/Header/PageHeader.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,14 @@ const PageHeader = ({
4949
showAnnouncementHeader,
5050
tippyProps,
5151
}: PageHeaderType) => {
52-
const { loginCount, setLoginCount, showGettingStartedCard, setShowGettingStartedCard, setGettingStartedClicked } =
53-
useMainContext()
52+
const {
53+
loginCount,
54+
setLoginCount,
55+
showGettingStartedCard,
56+
setShowGettingStartedCard,
57+
setGettingStartedClicked,
58+
setIsLicenseInfoDialogOpen,
59+
} = useMainContext()
5460
const { showSwitchThemeLocationTippy, handleShowSwitchThemeLocationTippyChange } = useTheme()
5561

5662
const { isTippyCustomized, tippyRedirectLink, TippyIcon, tippyMessage, onClickTippyButton, additionalContent } =
@@ -66,6 +72,10 @@ const PageHeader = ({
6672
)
6773
const [expiryDate, setExpiryDate] = useState(0)
6874

75+
const handleOpenLicenseInfoDialog = () => {
76+
setIsLicenseInfoDialogOpen(true)
77+
}
78+
6979
const getCurrentServerInfo = async () => {
7080
try {
7181
const { result } = await getServerInfo(true, true)
@@ -272,6 +282,7 @@ const PageHeader = ({
272282
fetchingServerInfo={currentServerInfo.fetchingServerInfo}
273283
setGettingStartedClicked={setGettingStartedClicked}
274284
showHelpCard={showHelpCard}
285+
openAboutDevtronDialog={handleOpenLicenseInfoDialog}
275286
/>
276287
)}
277288
{!window._env_.K8S_CLIENT &&

src/Shared/Components/Header/constants.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export const OSSHelpOptions: HelpOptionType[] = [
3939
name: 'Chat with support',
4040
link: DISCORD_LINK,
4141
icon: Chat,
42-
showSeparator: true,
4342
},
4443

4544
{

src/Shared/Components/Header/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ export interface HelpNavType {
6262
fetchingServerInfo: boolean
6363
setGettingStartedClicked: (isClicked: boolean) => void
6464
showHelpCard: boolean
65+
openAboutDevtronDialog: () => void
6566
}
6667

6768
export interface HelpOptionType {
6869
name: string
6970
link: string
7071
icon: React.FunctionComponent<React.SVGProps<SVGSVGElement>>
71-
showSeparator?: boolean
7272
}

0 commit comments

Comments
 (0)