Skip to content

Commit e177fe1

Browse files
authored
Merge pull request #2220 from redpanda-data/UX-870-remove-core-stat-from-mobx
UX 870 remove core stat from mobx
2 parents dabfa2f + a3bba90 commit e177fe1

21 files changed

Lines changed: 1846 additions & 1645 deletions

frontend/src/components/layout/header.tsx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ import { Box, Button, ColorModeSwitch, CopyButton, Flex } from '@redpanda-data/u
1313
import { Link, useLocation, useMatchRoute } from '@tanstack/react-router';
1414
import { Heading } from 'components/redpanda-ui/components/typography';
1515
import { cn } from 'components/redpanda-ui/lib/utils';
16-
import { computed } from 'mobx';
17-
import { observer } from 'mobx-react';
18-
import { Fragment } from 'react';
16+
import { Fragment, useMemo } from 'react';
1917

2018
import { isEmbedded } from '../../config';
2119
import { api } from '../../state/backend-api';
22-
import { type BreadcrumbEntry, uiState } from '../../state/ui-state';
20+
import { type BreadcrumbEntry, useUIStateStore } from '../../state/ui-state';
2321
import { IsDev } from '../../utils/env';
2422
import DataRefreshButton from '../misc/buttons/data-refresh/component';
2523
import { UserPreferencesButton } from '../misc/user-preferences';
@@ -69,16 +67,19 @@ function BreadcrumbHeaderRow({ useNewSidebar, breadcrumbItems }: BreadcrumbHeade
6967
);
7068
}
7169

72-
const AppPageHeader = observer(() => {
70+
function AppPageHeader() {
7371
const showRefresh = useShouldShowRefresh();
74-
7572
const shouldHideHeader = useShouldHideHeader();
7673
const useNewSidebar = !isEmbedded();
7774

78-
const breadcrumbItems = computed(() => {
79-
const items: BreadcrumbEntry[] = [...uiState.pageBreadcrumbs];
75+
const pageBreadcrumbs = useUIStateStore((s) => s.pageBreadcrumbs);
76+
const selectedClusterName = useUIStateStore((s) => s.selectedClusterName);
77+
const shouldHidePageHeader = useUIStateStore((s) => s.shouldHidePageHeader);
78+
79+
const breadcrumbItems = useMemo(() => {
80+
const items: BreadcrumbEntry[] = [...pageBreadcrumbs];
8081

81-
if (!isEmbedded() && uiState.selectedClusterName) {
82+
if (!isEmbedded() && selectedClusterName) {
8283
items.unshift({
8384
heading: '',
8485
title: 'Cluster',
@@ -87,18 +88,19 @@ const AppPageHeader = observer(() => {
8788
}
8889

8990
return items;
90-
}).get();
91+
}, [pageBreadcrumbs, selectedClusterName]);
9192

92-
const lastBreadcrumb = breadcrumbItems.pop();
93+
const lastBreadcrumb = breadcrumbItems.at(-1);
94+
const breadcrumbsExceptLast = breadcrumbItems.slice(0, -1);
9395

94-
if (shouldHideHeader || uiState.shouldHidePageHeader) {
96+
if (shouldHideHeader || shouldHidePageHeader) {
9597
return null;
9698
}
9799

98100
return (
99101
<Box>
100102
{/* we need to refactor out #mainLayout > div rule, for now I've added this box as a workaround */}
101-
<BreadcrumbHeaderRow breadcrumbItems={breadcrumbItems} useNewSidebar={useNewSidebar} />
103+
<BreadcrumbHeaderRow breadcrumbItems={breadcrumbsExceptLast} useNewSidebar={useNewSidebar} />
102104

103105
<Flex alignItems="center" justifyContent="space-between" pb={2}>
104106
<Flex alignItems="center">
@@ -140,7 +142,7 @@ const AppPageHeader = observer(() => {
140142
</Flex>
141143
</Box>
142144
);
143-
});
145+
}
144146

145147
export default AppPageHeader;
146148

frontend/src/components/license/feature-license-notification.tsx

Lines changed: 55 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Alert, AlertDescription, AlertIcon, Box, Flex, Text } from '@redpanda-data/ui';
22
import { Link } from 'components/redpanda-ui/components/typography';
3-
import { observer } from 'mobx-react';
43
import { type FC, type ReactElement, useEffect, useState } from 'react';
54

65
import {
@@ -173,66 +172,64 @@ const getLicenseAlertContentForFeature = (
173172
return null;
174173
};
175174

176-
export const FeatureLicenseNotification: FC<{ featureName: 'reassignPartitions' | 'rbac' }> = observer(
177-
({ featureName }) => {
178-
const [registerModalOpen, setIsRegisterModalOpen] = useState(false);
179-
180-
useEffect(() => {
181-
api.refreshClusterOverview().catch(() => {
182-
// Error handling managed by API layer
183-
});
184-
api.listLicenses().catch(() => {
185-
// Error handling managed by API layer
186-
});
187-
}, []);
188-
189-
const licenses = api.licenses
190-
.filter((lic) => lic.type === License_Type.TRIAL || lic.type === License_Type.COMMUNITY)
191-
.sort((a, b) => LICENSE_WEIGHT[a.type] - LICENSE_WEIGHT[b.type]); // Sort by priority
192-
193-
// Choose the license with the latest expiration time
194-
const license = getLatestExpiringLicense(licenses);
195-
196-
// Trial is either baked-in or extended. We need to check if any of the licenses are baked-in.
197-
// We say the trial is baked-in if and only if all the licenses are baked-in. There can be a situation where,
198-
// use has registered a license, it's updated in the brokers, but the console doesn't have the license re-loaded yet.
199-
const bakedInTrial = licenses.every((lic) => isBakedInTrial(lic));
200-
201-
const enterpriseFeaturesUsed = api.enterpriseFeaturesUsed;
202-
const alertContent = getLicenseAlertContentForFeature(
203-
featureName,
204-
license,
205-
enterpriseFeaturesUsed,
206-
bakedInTrial,
207-
() => {
208-
setIsRegisterModalOpen(true);
209-
}
210-
);
211-
212-
// This component needs info about whether we're using Redpanda or Kafka, without fetching clusterOverview first, we might get a malformed result
213-
if (api.clusterOverview === null) {
214-
return null;
175+
export const FeatureLicenseNotification: FC<{ featureName: 'reassignPartitions' | 'rbac' }> = ({ featureName }) => {
176+
const [registerModalOpen, setIsRegisterModalOpen] = useState(false);
177+
178+
useEffect(() => {
179+
api.refreshClusterOverview().catch(() => {
180+
// Error handling managed by API layer
181+
});
182+
api.listLicenses().catch(() => {
183+
// Error handling managed by API layer
184+
});
185+
}, []);
186+
187+
const licenses = api.licenses
188+
.filter((lic) => lic.type === License_Type.TRIAL || lic.type === License_Type.COMMUNITY)
189+
.sort((a, b) => LICENSE_WEIGHT[a.type] - LICENSE_WEIGHT[b.type]); // Sort by priority
190+
191+
// Choose the license with the latest expiration time
192+
const license = getLatestExpiringLicense(licenses);
193+
194+
// Trial is either baked-in or extended. We need to check if any of the licenses are baked-in.
195+
// We say the trial is baked-in if and only if all the licenses are baked-in. There can be a situation where,
196+
// use has registered a license, it's updated in the brokers, but the console doesn't have the license re-loaded yet.
197+
const bakedInTrial = licenses.every((lic) => isBakedInTrial(lic));
198+
199+
const enterpriseFeaturesUsed = api.enterpriseFeaturesUsed;
200+
const alertContent = getLicenseAlertContentForFeature(
201+
featureName,
202+
license,
203+
enterpriseFeaturesUsed,
204+
bakedInTrial,
205+
() => {
206+
setIsRegisterModalOpen(true);
215207
}
208+
);
216209

217-
if (!license) {
218-
return null;
219-
}
210+
// This component needs info about whether we're using Redpanda or Kafka, without fetching clusterOverview first, we might get a malformed result
211+
if (api.clusterOverview === null) {
212+
return null;
213+
}
220214

221-
if (alertContent === null) {
222-
return null;
223-
}
215+
if (!license) {
216+
return null;
217+
}
218+
219+
if (alertContent === null) {
220+
return null;
221+
}
224222

225-
const { message, status } = alertContent;
223+
const { message, status } = alertContent;
226224

227-
return (
228-
<Box>
229-
<Alert mb={4} status={status} variant="subtle">
230-
<AlertIcon />
231-
<AlertDescription>{message}</AlertDescription>
232-
</Alert>
225+
return (
226+
<Box>
227+
<Alert mb={4} status={status} variant="subtle">
228+
<AlertIcon />
229+
<AlertDescription>{message}</AlertDescription>
230+
</Alert>
233231

234-
<RegisterModal isOpen={registerModalOpen} onClose={() => setIsRegisterModalOpen(false)} />
235-
</Box>
236-
);
237-
}
238-
);
232+
<RegisterModal isOpen={registerModalOpen} onClose={() => setIsRegisterModalOpen(false)} />
233+
</Box>
234+
);
235+
};

frontend/src/components/license/license-notification.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Alert, AlertDescription, AlertIcon, Box, Button, Flex } from '@redpanda-data/ui';
22
import { Link, useLocation } from '@tanstack/react-router';
3-
import { observer } from 'mobx-react';
43

54
import {
65
coreHasEnterpriseFeatures,
@@ -16,7 +15,7 @@ import { api } from '../../state/backend-api';
1615
import { capitalizeFirst } from '../../utils/utils';
1716

1817
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: complex business logic
19-
export const LicenseNotification = observer(() => {
18+
export const LicenseNotification = () => {
2019
const location = useLocation();
2120

2221
// This Global License Notification banner is used only for Enterprise licenses
@@ -134,4 +133,4 @@ export const LicenseNotification = observer(() => {
134133
</Alert>
135134
</Box>
136135
);
137-
});
136+
};

frontend/src/components/license/overview-license-notification.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Alert, AlertDescription, AlertIcon, Box, Flex, Text } from '@redpanda-data/ui';
22
import { Link } from 'components/redpanda-ui/components/typography';
3-
import { observer } from 'mobx-react';
43
import { type FC, type ReactElement, useEffect, useState } from 'react';
54

65
import {
@@ -254,7 +253,7 @@ const getLicenseAlertContent = (
254253
return null;
255254
};
256255

257-
export const OverviewLicenseNotification: FC = observer(() => {
256+
export const OverviewLicenseNotification: FC = () => {
258257
const [registerModalOpen, setIsRegisterModalOpen] = useState(false);
259258

260259
useEffect(() => {
@@ -297,4 +296,4 @@ export const OverviewLicenseNotification: FC = observer(() => {
297296
<RegisterModal isOpen={registerModalOpen} onClose={() => setIsRegisterModalOpen(false)} />
298297
</Box>
299298
);
300-
});
299+
};

frontend/src/components/license/register-modal.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
VStack,
2121
} from '@redpanda-data/ui';
2222
import { CheckIcon } from 'components/icons';
23-
import { observer } from 'mobx-react';
2423
import { useState } from 'react';
2524
import { Controller, type SubmitHandler, useForm } from 'react-hook-form';
2625
import { capitalizeFirst } from 'utils/utils';
@@ -62,7 +61,7 @@ type RegisterModalProps = {
6261
onClose: () => void;
6362
};
6463

65-
export const RegisterModal = observer(({ isOpen, onClose }: RegisterModalProps) => {
64+
export const RegisterModal = ({ isOpen, onClose }: RegisterModalProps) => {
6665
const [isSubmitting, setIsSubmitting] = useState(false);
6766
const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
6867
const [isSuccess, setIsSuccess] = useState(false);
@@ -309,4 +308,4 @@ export const RegisterModal = observer(({ isOpen, onClose }: RegisterModalProps)
309308
</ModalContent>
310309
</Modal>
311310
);
312-
});
311+
};

0 commit comments

Comments
 (0)