UNPKG

@kinvolk/headlamp-plugin

Version:

The needed infrastructure for building Headlamp plugins.

101 lines (100 loc) 5.63 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /* * Copyright 2025 The Kubernetes Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Button from '@mui/material/Button'; import Grid from '@mui/material/Grid'; import MuiToggledButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { styled } from '@mui/system'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { generatePath, useHistory } from 'react-router-dom'; import { getClusterAppearanceFromMeta } from '../../../helpers/clusterAppearance'; import { isElectron } from '../../../helpers/isElectron'; import { getRecentClusters, setRecentCluster } from '../../../helpers/recentClusters'; import { formatClusterPathParam, getClusterPrefixedPath } from '../../../lib/cluster'; import { createRouteURL } from '../../../lib/router/createRouteURL'; import { MULTI_HOME_ENABLED } from './config'; import SquareButton from './SquareButton'; const ToggleButton = styled(MuiToggledButton)({ textTransform: 'none', }); function ClusterButton(props) { const { cluster, onClick = undefined, focusedRef } = props; const appearance = getClusterAppearanceFromMeta(cluster?.name || ''); const icon = appearance.icon || 'mdi:kubernetes'; return (_jsx(SquareButton, { focusRipple: true, icon: icon, iconColor: appearance.accentColor, label: cluster.name, ref: focusedRef, onClick: onClick })); } export default function RecentClusters(props) { const { clusters } = props; const history = useHistory(); const focusedRef = React.useCallback((node) => { if (node !== null) { node.focus(); } }, []); const { t } = useTranslation('translation'); const [selectedClusters, setSelectedClusters] = React.useState([]); const recentClustersLabelId = 'recent-clusters-label'; const maxRecentClusters = 3; // We slice it here for the maximum recent clusters just for extra safety, since this // is an entry point to the rest of the functionality const recentClusterNames = getRecentClusters().slice(0, maxRecentClusters); let recentClusters = []; // If we have more than the maximum number of recent clusters allowed, we show the most // recent ones. Otherwise, just show the clusters in the order they are received. if (clusters.length > maxRecentClusters) { // Get clusters matching the recent cluster names, if they exist still. recentClusters = recentClusterNames .map(name => clusters.find(cluster => cluster.name === name)) .filter(item => !!item); // See whether we need to fill with new clusters (when the recent clusters were less than the // maximum/wanted). const neededClusters = maxRecentClusters - recentClusters.length; if (neededClusters > 0) { recentClusters = recentClusters.concat(clusters.filter(item => !recentClusters.includes(item)).slice(0, neededClusters)); } } else { recentClusters = clusters; } function onClusterButtonClicked(cluster) { setRecentCluster(cluster); history.push({ pathname: generatePath(getClusterPrefixedPath(), { cluster: cluster.name, }), }); } /** * Callback for when the "View" button is clicked. It will navigate to the selected clusters. */ function onViewClusters() { selectedClusters.forEach(cluster => { setRecentCluster(cluster); }); history.push({ pathname: generatePath(getClusterPrefixedPath(), { cluster: formatClusterPathParam(selectedClusters.map(cluster => cluster.name)), }), }); } const doMulti = recentClusters.length > 1 && MULTI_HOME_ENABLED; return (_jsxs(Grid, { role: "group", "aria-labelledby": recentClustersLabelId, item: true, container: true, alignItems: "flex-start", spacing: 2, children: [!doMulti && recentClusters.map((cluster, i) => (_jsx(Grid, { item: true, children: _jsx(ClusterButton, { focusedRef: i === 0 ? focusedRef : undefined, cluster: cluster, onClick: () => onClusterButtonClicked(cluster) }) }, cluster.name))), doMulti && (_jsxs(Grid, { container: true, item: true, alignItems: "center", children: [_jsx(ToggleButtonGroup, { value: selectedClusters, onChange: (event, clusters) => setSelectedClusters(clusters), "aria-label": t('Selected clusters'), exclusive: false, children: recentClusters.map(cluster => (_jsx(ToggleButton, { value: cluster, children: cluster.name }, cluster.name))) }), _jsx(Grid, { item: true, pl: 2, children: _jsx(Button, { variant: "contained", disabled: selectedClusters.length < 1, color: "primary", onClick: onViewClusters, children: t('View') }) })] })), isElectron() && (_jsx(Grid, { item: true, children: _jsx(SquareButton, { onClick: () => { history.push(createRouteURL('addCluster')); }, label: t('Load cluster'), icon: "mdi:plus-circle-outline", primary: true }) }))] })); }