Skip to content

Commit

Permalink
Formatted code:
Browse files Browse the repository at this point in the history
  • Loading branch information
jvorcak committed Nov 29, 2024
1 parent 0be192a commit b5ee4b6
Show file tree
Hide file tree
Showing 13 changed files with 561 additions and 435 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/RequireAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default class RequireAuth extends Component<{ children: ReactNode }> {
},
};
} else if (r.status === 403) {
void handleExpiredLicenseError(r)
void handleExpiredLicenseError(r);
}
});

Expand Down
244 changes: 143 additions & 101 deletions frontend/src/components/license/FeatureLicenseNotification.tsx
Original file line number Diff line number Diff line change
@@ -1,132 +1,174 @@
import { Alert, AlertDescription, AlertIcon, Box, Button, Flex, Link, Text } from '@redpanda-data/ui';
import { observer } from 'mobx-react';
import { FC, ReactElement, useEffect } from 'react';
import { License, License_Type, ListEnterpriseFeaturesResponse_Feature } from '../../protogen/redpanda/api/console/v1alpha1/license_pb';
import { getEnterpriseCTALink, getMillisecondsToExpiration, getPrettyExpirationDate, getPrettyTimeToExpiration, LICENSE_WEIGHT, MS_IN_DAY, coreHasEnterpriseFeatures, UploadLicenseButton, UpgradeButton } from './licenseUtils';
import {
License,
License_Type,
ListEnterpriseFeaturesResponse_Feature,
} from '../../protogen/redpanda/api/console/v1alpha1/license_pb';
import {
getEnterpriseCTALink,
getMillisecondsToExpiration,
getPrettyExpirationDate,
getPrettyTimeToExpiration,
LICENSE_WEIGHT,
MS_IN_DAY,
coreHasEnterpriseFeatures,
UploadLicenseButton,
UpgradeButton,
} from './licenseUtils';
import { api } from '../../state/backendApi';

const getLicenseAlertContentForFeature = (featureName: 'rbac' | 'reassignPartitions', license: License | undefined, enterpriseFeaturesUsed: ListEnterpriseFeaturesResponse_Feature[]): { message: ReactElement, status: 'warning' | 'info' } | null => {
if (license === undefined || license.type !== License_Type.TRIAL) {
return null
}
const getLicenseAlertContentForFeature = (
featureName: 'rbac' | 'reassignPartitions',
license: License | undefined,
enterpriseFeaturesUsed: ListEnterpriseFeaturesResponse_Feature[],
): { message: ReactElement; status: 'warning' | 'info' } | null => {
if (license === undefined || license.type !== License_Type.TRIAL) {
return null;
}

const msToExpiration = getMillisecondsToExpiration(license);
const msToExpiration = getMillisecondsToExpiration(license);

// Redpanda
if (api.isRedpanda) {
if (msToExpiration > 15 * MS_IN_DAY && msToExpiration < 30 * MS_IN_DAY && coreHasEnterpriseFeatures(enterpriseFeaturesUsed)) {
return {
message: <Box>
<Text>This is an enterprise feature, active until {getPrettyExpirationDate(license)}.</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>,
status: 'info',
}
} else if (msToExpiration > 0 && msToExpiration < 15 * MS_IN_DAY && coreHasEnterpriseFeatures(enterpriseFeaturesUsed)) {
return {
message: <Box>
<Text>
Your Redpanda Enterprise trial is expiring in {getPrettyTimeToExpiration(license)}; at that point, your enterprise features will become unavailable. To get a full Redpanda Enterprise license, <Link href={getEnterpriseCTALink('upgrade')} target="_blank">contact us</Link>.
</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton/>
<UpgradeButton />
</Flex>
</Box>,
status: 'warning'
};
}
} else {
// Kafka
if (msToExpiration > 15 * MS_IN_DAY && msToExpiration < 30 * MS_IN_DAY) {
if (license.type === License_Type.TRIAL) {
return {
message:
<Box>
<Text>
This is an enterprise feature. Your trial is active until {getPrettyExpirationDate(license)}
</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>,
status: 'info'
};
} else {
return {
message: <Box>
<Text>
This is a Redpanda Enterprise feature. Try it with our <Link href={getEnterpriseCTALink('tryEnterprise')} target="_blank">Redpanda Enterprise Trial</Link>.
</Text>
</Box>,
status: 'info'
};
}
} else if (msToExpiration > 0 && msToExpiration < 15 * MS_IN_DAY && license.type === License_Type.TRIAL) {
return {
message: <Box>
<Text>
Your Redpanda Enterprise trial is expiring in {getPrettyTimeToExpiration(license)}; at that point, your enterprise features will become unavailable. To get a full Redpanda Enterprise license, <Link href={getEnterpriseCTALink('upgrade')} target="_blank">contact us</Link>.
</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>,
status: 'warning'
};
}
// Redpanda
if (api.isRedpanda) {
if (
msToExpiration > 15 * MS_IN_DAY &&
msToExpiration < 30 * MS_IN_DAY &&
coreHasEnterpriseFeatures(enterpriseFeaturesUsed)
) {
return {
message: (
<Box>
<Text>This is an enterprise feature, active until {getPrettyExpirationDate(license)}.</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>
),
status: 'info',
};
} else if (
msToExpiration > 0 &&
msToExpiration < 15 * MS_IN_DAY &&
coreHasEnterpriseFeatures(enterpriseFeaturesUsed)
) {
return {
message: (
<Box>
<Text>
Your Redpanda Enterprise trial is expiring in {getPrettyTimeToExpiration(license)}; at that point, your
enterprise features will become unavailable. To get a full Redpanda Enterprise license,{' '}
<Link href={getEnterpriseCTALink('upgrade')} target="_blank">
contact us
</Link>
.
</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>
),
status: 'warning',
};
}
} else {
// Kafka
if (msToExpiration > 15 * MS_IN_DAY && msToExpiration < 30 * MS_IN_DAY) {
if (license.type === License_Type.TRIAL) {
return {
message: (
<Box>
<Text>This is an enterprise feature. Your trial is active until {getPrettyExpirationDate(license)}</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>
),
status: 'info',
};
} else {
return {
message: (
<Box>
<Text>
This is a Redpanda Enterprise feature. Try it with our{' '}
<Link href={getEnterpriseCTALink('tryEnterprise')} target="_blank">
Redpanda Enterprise Trial
</Link>
.
</Text>
</Box>
),
status: 'info',
};
}
} else if (msToExpiration > 0 && msToExpiration < 15 * MS_IN_DAY && license.type === License_Type.TRIAL) {
return {
message: (
<Box>
<Text>
Your Redpanda Enterprise trial is expiring in {getPrettyTimeToExpiration(license)}; at that point, your
enterprise features will become unavailable. To get a full Redpanda Enterprise license,{' '}
<Link href={getEnterpriseCTALink('upgrade')} target="_blank">
contact us
</Link>
.
</Text>
<Flex gap={2} my={2}>
<UploadLicenseButton />
<UpgradeButton />
</Flex>
</Box>
),
status: 'warning',
};
}
}

return null;
return null;
};

export const FeatureLicenseNotification: FC<{ featureName: 'reassignPartitions' | 'rbac' }> = observer(({ featureName}) => {
export const FeatureLicenseNotification: FC<{ featureName: 'reassignPartitions' | 'rbac' }> = observer(
({ featureName }) => {
useEffect(() => {
void api.refreshClusterOverview()
void api.listLicenses();
void api.refreshClusterOverview();
void api.listLicenses();
}, []);

const license = api
.licenses
.filter(license => license.type === License_Type.TRIAL || license.type === License_Type.COMMUNITY)
.sort((a, b) => LICENSE_WEIGHT[a.type] - LICENSE_WEIGHT[b.type]) // Sort by priority
.first();
const license = api.licenses
.filter((license) => license.type === License_Type.TRIAL || license.type === License_Type.COMMUNITY)
.sort((a, b) => LICENSE_WEIGHT[a.type] - LICENSE_WEIGHT[b.type]) // Sort by priority
.first();

const enterpriseFeaturesUsed = api.enterpriseFeaturesUsed
const enterpriseFeaturesUsed = api.enterpriseFeaturesUsed;
const alertContent = getLicenseAlertContentForFeature(featureName, license, enterpriseFeaturesUsed);

// This component needs info about whether we're using Redpanda or Kafka, without fetching clusterOverview first, we might get a malformed result
if (api.clusterOverview === null) {
return null
return null;
}

if (!license) {
return null;
return null;
}

if (alertContent === null) {
return null;
return null;
}

const { message, status } = alertContent;

return (
<Box>
<Alert
mb={4}
status={status}
variant="subtle"
>
<AlertIcon/>
<AlertDescription>
{message}
</AlertDescription>
</Alert>
</Box>
<Box>
<Alert mb={4} status={status} variant="subtle">
<AlertIcon />
<AlertDescription>{message}</AlertDescription>
</Alert>
</Box>
);
});
},
);
66 changes: 35 additions & 31 deletions frontend/src/components/license/LicenseNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,24 @@ import {
} from './licenseUtils';

export const LicenseNotification = observer(() => {
const location = useLocation();
const location = useLocation();

// This Global License Notification banner is used only for Enterprise licenses
// Trial Licences are handled by OverviewLicenseNotification and FeatureLicenseNotification.
// Community Licenses can't expire at all.
const enterpriseLicenses = api.licenses.filter(license => license.type === License_Type.ENTERPRISE)
// This Global License Notification banner is used only for Enterprise licenses
// Trial Licences are handled by OverviewLicenseNotification and FeatureLicenseNotification.
// Community Licenses can't expire at all.
const enterpriseLicenses = api.licenses.filter((license) => license.type === License_Type.ENTERPRISE);

const visibleExpiredEnterpriseLicenses = enterpriseLicenses.filter(licenseIsExpired) ?? [];
const soonToExpireLicenses = enterpriseLicenses
.filter(license => licenseSoonToExpire(license))
?? [];
const visibleExpiredEnterpriseLicenses = enterpriseLicenses.filter(licenseIsExpired) ?? [];
const soonToExpireLicenses = enterpriseLicenses.filter((license) => licenseSoonToExpire(license)) ?? [];

const showSomeLicenseExpirationInfo = visibleExpiredEnterpriseLicenses.length || soonToExpireLicenses.length;
const showSomeLicenseExpirationInfo = visibleExpiredEnterpriseLicenses.length || soonToExpireLicenses.length;

if (api.licensesLoaded === undefined) {
return null;
}

// For these paths, we don't need to show a notification banner because the pages themselves handle license management
if (location.pathname === '/admin/upload-license' || location.pathname === '/trial-expired') {
if (location.pathname === '/admin/upload-license' || location.pathname === '/trial-expired') {
return null;
}

Expand All @@ -41,20 +39,20 @@ export const LicenseNotification = observer(() => {

const activeEnterpriseFeatures = api.enterpriseFeaturesUsed.filter((x) => x.enabled);

const visibleSoonToExpireLicenses = soonToExpireLicenses.length > 1 && new Set(soonToExpireLicenses.map(x => x.expiresAt)).size === 1 ?
soonToExpireLicenses.filter(x => x.source === License_Source.REDPANDA_CORE) : soonToExpireLicenses
const visibleSoonToExpireLicenses =
soonToExpireLicenses.length > 1 && new Set(soonToExpireLicenses.map((x) => x.expiresAt)).size === 1
? soonToExpireLicenses.filter((x) => x.source === License_Source.REDPANDA_CORE)
: soonToExpireLicenses;

const visibleExpiredLicenses = visibleExpiredEnterpriseLicenses.length > 1 && new Set(visibleExpiredEnterpriseLicenses.map(x => x.expiresAt)).size === 1 ?
visibleExpiredEnterpriseLicenses.filter(x => x.source === License_Source.REDPANDA_CORE) : visibleExpiredEnterpriseLicenses
const visibleExpiredLicenses =
visibleExpiredEnterpriseLicenses.length > 1 &&
new Set(visibleExpiredEnterpriseLicenses.map((x) => x.expiresAt)).size === 1
? visibleExpiredEnterpriseLicenses.filter((x) => x.source === License_Source.REDPANDA_CORE)
: visibleExpiredEnterpriseLicenses;




return (
<Box>
<Alert
mb={4}
status="info" variant="subtle">
return (
<Box>
<Alert mb={4} status="info" variant="subtle">
<AlertIcon />
<AlertDescription>
{visibleSoonToExpireLicenses.length > 0 && (
Expand Down Expand Up @@ -87,12 +85,18 @@ export const LicenseNotification = observer(() => {
</Text>
)}

<Flex gap={2} my={2}>
{api.isAdminApiConfigured && <Button variant="outline" size="sm" as={ReactRouterLink} to="/admin/upload-license">Upload license</Button>}
<Button variant="outline" size="sm" as="a" target="_blank" href="https://support.redpanda.com/">Request a license</Button>
</Flex>
</AlertDescription>
</Alert>
</Box>
);
<Flex gap={2} my={2}>
{api.isAdminApiConfigured && (
<Button variant="outline" size="sm" as={ReactRouterLink} to="/admin/upload-license">
Upload license
</Button>
)}
<Button variant="outline" size="sm" as="a" target="_blank" href="https://support.redpanda.com/">
Request a license
</Button>
</Flex>
</AlertDescription>
</Alert>
</Box>
);
});
Loading

0 comments on commit b5ee4b6

Please sign in to comment.