Skip to content

Commit d624242

Browse files
committed
Merge branch 'main' of https://github.com/devtron-labs/dashboard into chore/sync-activate-license
2 parents 6d135b5 + 0fc42ac commit d624242

File tree

8 files changed

+183
-18
lines changed

8 files changed

+183
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "1.11.0-pre-6",
7+
"@devtron-labs/devtron-fe-common-lib": "1.11.0-pre-7",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/App.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ import {
4242
} from './components/common'
4343
import { UPDATE_AVAILABLE_TOAST_PROGRESS_BG, URLS } from './config'
4444
import { validateToken } from './services/service'
45+
import ActivateLicense from '@Pages/License/ActivateLicense'
4546

4647
const NavigationRoutes = lazy(() => import('./components/common/navigation/NavigationRoutes'))
4748
const Login = lazy(() => import('./components/login/Login'))
4849
const GenericDirectApprovalModal = importComponentFromFELibrary('GenericDirectApprovalModal')
49-
const ActivateLicense = importComponentFromFELibrary('ActivateLicense', null, 'function')
5050

5151
export default function App() {
5252
const onlineToastRef = useRef(null)
@@ -160,7 +160,6 @@ export default function App() {
160160
}
161161

162162
useEffect(() => {
163-
164163
if (navigator.serviceWorker) {
165164
navigator.serviceWorker.addEventListener('controllerchange', handleControllerChange)
166165
}
@@ -328,7 +327,7 @@ export default function App() {
328327
<div className="full-height-width bg__tertiary">
329328
<Reload />
330329
</div>
331-
) : (
330+
) : (
332331
<ErrorBoundary>
333332
<BreadcrumbStore>
334333
<Switch>
@@ -340,11 +339,9 @@ export default function App() {
340339
/>
341340
</Route>
342341
)}
343-
{ActivateLicense && (
344-
<Route path={CommonURLS.LICENSE_AUTH}>
345-
<ActivateLicense />
346-
</Route>
347-
)}
342+
<Route path={CommonURLS.LICENSE_AUTH}>
343+
<ActivateLicense />
344+
</Route>
348345
{!window._env_.K8S_CLIENT && <Route path="/login" component={Login} />}
349346
<Route path="/" render={() => <NavigationRoutes />} />
350347
<Redirect

src/Pages/License/ActivateLicense.tsx

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { useEffect, useState } from 'react'
2+
import { useHistory } from 'react-router-dom'
3+
4+
import {
5+
ActivateLicenseDialog,
6+
API_STATUS_CODES,
7+
Button,
8+
ButtonVariantType,
9+
CONTACT_SUPPORT_LINK,
10+
DevtronLicenseCard,
11+
DevtronProgressing,
12+
ENTERPRISE_SUPPORT_LINK,
13+
ErrorScreenManager,
14+
getHandleOpenURL,
15+
ICDevtronWithBorder,
16+
Icon,
17+
InfoBlock,
18+
LicensingErrorCodes,
19+
LoginBanner,
20+
URLS,
21+
useAsync,
22+
useTheme,
23+
} from '@devtron-labs/devtron-fe-common-lib'
24+
25+
import { getDevtronLicenseInfo } from './service'
26+
27+
const ActivateLicense = () => {
28+
const history = useHistory()
29+
const [isLoading, licenseData, licenseDataError, reloadLicenseData] = useAsync(getDevtronLicenseInfo, [])
30+
const [showActivateDialog, setShowActivateDialog] = useState<boolean>(false)
31+
const { appTheme } = useTheme()
32+
33+
const redirectToLogin = () => {
34+
history.replace(URLS.LOGIN_SSO)
35+
}
36+
37+
useEffect(() => {
38+
if (isLoading) {
39+
return
40+
}
41+
42+
// licenseDataError.code === 404 means, oss and licensing does not exist
43+
// In case licenseStatusError is null, license is valid
44+
if (licenseDataError?.code === API_STATUS_CODES.NOT_FOUND || !licenseData.licenseStatusError) {
45+
redirectToLogin()
46+
return
47+
}
48+
49+
if (licenseData.licenseStatusError.code === LicensingErrorCodes.LicKeyNotFound) {
50+
setShowActivateDialog(true)
51+
}
52+
}, [isLoading, licenseData])
53+
54+
if (isLoading) {
55+
return <DevtronProgressing parentClasses="bg__primary flex full-height-width" classes="icon-dim-80" />
56+
}
57+
58+
if (licenseDataError) {
59+
return (
60+
<div className="full-height-width bg__tertiary">
61+
<ErrorScreenManager code={licenseDataError?.code} reload={reloadLicenseData} />
62+
</div>
63+
)
64+
}
65+
66+
const handleChangeLicense = () => {
67+
setShowActivateDialog(true)
68+
}
69+
70+
const renderInvalidLicenseDialog = () => (
71+
<div className="flexbox-col p-36 dc__gap-32 w-400 border__primary br-12">
72+
<div className="flexbox-col dc__gap-20">
73+
<ICDevtronWithBorder />
74+
<div className="flexbox-col dc__gap-4">
75+
<div className="fs-20 lh-1-5 fw-7 cn-9 font-merriweather dc__truncate">
76+
{licenseData.enterpriseName}
77+
</div>
78+
<div className="fs-16 lh-1-5 cr-5 fw-4">Your license key is no longer valid</div>
79+
</div>
80+
</div>
81+
{licenseData.licenseStatusError &&
82+
licenseData.licenseStatusError.code !== LicensingErrorCodes.LicenseExpired ? (
83+
<InfoBlock
84+
heading="Need help?"
85+
description={
86+
<span>
87+
For further details mail us at&nbsp;
88+
<a href={`mailto:${ENTERPRISE_SUPPORT_LINK}`}>{ENTERPRISE_SUPPORT_LINK}</a> or contact
89+
Devtron Support
90+
</span>
91+
}
92+
variant="help"
93+
buttonProps={{
94+
text: 'Contact Support',
95+
variant: ButtonVariantType.text,
96+
onClick: getHandleOpenURL(CONTACT_SUPPORT_LINK),
97+
dataTestId: 'contact-support',
98+
startIcon: <Icon name="ic-chat-circle-dots" color="B500" size={16} />,
99+
}}
100+
layout="column"
101+
/>
102+
) : (
103+
<DevtronLicenseCard
104+
enterpriseName={licenseData.enterpriseName}
105+
expiryDate={licenseData.expiryDate}
106+
ttl={licenseData.ttl}
107+
licenseStatus={licenseData.licenseStatus}
108+
isTrial={licenseData.isTrial}
109+
licenseSuffix={licenseData.licenseSuffix}
110+
appTheme={appTheme}
111+
/>
112+
)}
113+
<div className="flex dc__content-space">
114+
<span>Have another license key?</span>
115+
<Button
116+
dataTestId="change-license"
117+
text="Change license"
118+
variant={ButtonVariantType.text}
119+
onClick={handleChangeLicense}
120+
/>
121+
</div>
122+
</div>
123+
)
124+
125+
return (
126+
<div className="full-height-width bg__secondary dc__grid-half">
127+
<div className="flexbox p-16">
128+
<LoginBanner />
129+
</div>
130+
<div className="flex">
131+
{showActivateDialog ? (
132+
<ActivateLicenseDialog
133+
fingerprint={licenseData.fingerprint || ''}
134+
enterpriseName={licenseData.enterpriseName}
135+
handleLicenseActivateSuccess={redirectToLogin}
136+
/>
137+
) : (
138+
renderInvalidLicenseDialog()
139+
)}
140+
</div>
141+
</div>
142+
)
143+
}
144+
145+
export default ActivateLicense

src/Pages/License/service.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// NOTE: This API is used to check if the license is valid or not at APP.TSX level
2+
3+
import {
4+
DevtronLicenseDTO,
5+
DevtronLicenseInfo,
6+
get,
7+
parseDevtronLicenseData,
8+
ROUTES,
9+
} from '@devtron-labs/devtron-fe-common-lib'
10+
11+
// Only gives complete response if the license is invalid else return only fingerprint
12+
export const getDevtronLicenseInfo = async (): Promise<DevtronLicenseInfo> => {
13+
const { result } = await get<DevtronLicenseDTO>(ROUTES.LICENSE_DATA, { preventLicenseRedirect: true })
14+
return parseDevtronLicenseData(result)
15+
}

src/components/ResourceBrowser/ResourceList/ClusterUpgradeCompatibilityInfo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ const ClusterUpgradeCompatibilityInfo = ({
104104
}
105105

106106
return (
107-
<div className="resource-browser">
108-
<div className="dc__overflow-auto p-8">
107+
<div className="flexbox h-100 dc__overflow-auto">
108+
<div className="dc__overflow-auto p-8 w-220 dc__no-shrink">
109109
<CollapsibleList tabType="navLink" config={sidebarConfig} onCollapseBtnClick={onCollapseBtnClick} />
110110
</div>
111111
<BaseResourceList

src/components/cdPipeline/CDPipeline.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ export default function CDPipeline({
279279

280280
const isGitOpsRepoNotConfigured = isExternalArgoPipeline ? false : isGitOpsRepoNotConfiguredProp
281281

282+
const areMandatoryPluginPossible = !!processPluginData && !isTemplateView
283+
282284
const handleHideScopedVariableWidgetUpdate: PipelineContext['handleHideScopedVariableWidgetUpdate'] = (
283285
hideScopedVariableWidgetValue: boolean,
284286
) => {
@@ -312,7 +314,7 @@ export default function CDPipeline({
312314
const postBuildPluginIds = getPluginIdsFromBuildStage(form.postBuildStage)
313315
const uniquePluginIds = Array.from(new Set([...preBuildPluginIds, ...postBuildPluginIds]))
314316

315-
if (processPluginData) {
317+
if (areMandatoryPluginPossible) {
316318
await getMandatoryPluginData(form, uniquePluginIds)
317319
return
318320
}
@@ -448,7 +450,7 @@ export default function CDPipeline({
448450
}
449451

450452
const getMandatoryPluginData: BuildCDProps['getMandatoryPluginData'] = async (form, requiredPluginIds = []) => {
451-
if (!processPluginData || isTemplateView) {
453+
if (!areMandatoryPluginPossible) {
452454
return
453455
}
454456

src/components/globalConfigurations/GlobalConfiguration.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ const NavItem = ({ serverMode }) => {
283283
moduleName: ModuleNameMap.NOTIFICATION,
284284
isAvailableInEA: false,
285285
},
286-
...(window._env_.FEATURE_APPLICATION_TEMPLATES_ENABLE
286+
...(window._env_.FEATURE_APPLICATION_TEMPLATES_ENABLE && DevtronAppTemplates
287287
? [
288288
{
289289
name: 'Application Templates',

yarn.lock

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,10 +1126,10 @@
11261126
dependencies:
11271127
"@jridgewell/trace-mapping" "0.3.9"
11281128

1129-
"@devtron-labs/[email protected]6":
1130-
version "1.11.0-pre-6"
1131-
resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-1.11.0-pre-6.tgz#e74d94c895e0fdbbe4101341d8d00444a4bdf792"
1132-
integrity sha512-nNQOtzsXbs+c0H/EcR00ucsl7X/VjeOZ3spWDcZ3PQbSC+kpi4bHkcQFyAv3H2YGf8C6QVNeoTPtmfr+r/Vsmg==
1129+
"@devtron-labs/[email protected]7":
1130+
version "1.11.0-pre-7"
1131+
resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-1.11.0-pre-7.tgz#97dd5ce110cce44ace8651f090e2f8c6efb5adeb"
1132+
integrity sha512-CMZApIzeQCbV9t4AHRz11yxLuFq4OEdpoEngAovaGo2qp5upAUlN2ADn0i89ziXqOMVEu89xRQ/P3F6IpJRGgQ==
11331133
dependencies:
11341134
"@codemirror/lang-json" "6.0.1"
11351135
"@codemirror/lang-yaml" "6.1.2"
@@ -1154,6 +1154,7 @@
11541154
jsonpath-plus "^10.3.0"
11551155
marked "^13.0.3"
11561156
nanoid "^3.3.8"
1157+
qrcode.react "^4.2.0"
11571158
react-canvas-confetti "^2.0.7"
11581159
react-dates "^21.8.0"
11591160
react-diff-viewer-continued "^3.4.0"
@@ -7274,6 +7275,11 @@ punycode@^2.1.0:
72747275
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
72757276
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
72767277

7278+
qrcode.react@^4.2.0:
7279+
version "4.2.0"
7280+
resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-4.2.0.tgz#1bce8363f348197d145c0da640929a24c83cbca3"
7281+
integrity sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==
7282+
72777283
query-string@^7.1.1:
72787284
version "7.1.3"
72797285
resolved "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz"

0 commit comments

Comments
 (0)