UNPKG

@kinvolk/headlamp-plugin

Version:

The needed infrastructure for building Headlamp plugins.

98 lines (97 loc) 4.58 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 { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { useLocation } from 'react-router'; import DaemonSet from '../../../lib/k8s/daemonSet'; import Deployment from '../../../lib/k8s/deployment'; import StatefulSet from '../../../lib/k8s/statefulSet'; import { clusterAction } from '../../../redux/clusterActionSlice'; import { EventStatus, HeadlampEventType, useEventCallback, } from '../../../redux/headlampEventSlice'; import ActionButton from '../ActionButton'; import AuthVisible from './AuthVisible'; import RollbackDialog from './RollbackDialog'; /** * Type guard to check if a KubeObject is a resource that supports rollback. * Currently supports Deployment, DaemonSet, and StatefulSet. */ export function isRollbackableResource(item) { return Deployment.isClassOf(item) || DaemonSet.isClassOf(item) || StatefulSet.isClassOf(item); } /** * RollbackButton component for rolling back Workloads to a selected revision. * * This component provides a button that, when clicked, shows a revision selection * dialog where the user can pick a specific revision to rollback to. * * Supported Resources: * - Deployment (via ReplicaSets) * - DaemonSet (via ControllerRevisions) * - StatefulSet (via ControllerRevisions) */ export function RollbackButton(props) { const dispatch = useDispatch(); const { item, buttonStyle, afterConfirm } = props; const [openDialog, setOpenDialog] = useState(false); const location = useLocation(); const { t } = useTranslation(['translation']); const dispatchRollbackEvent = useEventCallback(HeadlampEventType.ROLLBACK_RESOURCE); const resource = item && isRollbackableResource(item) ? item : null; const getRevisionHistory = useCallback(() => { return resource ? resource.getRevisionHistory() : Promise.resolve([]); }, [resource]); if (!resource) { return null; } const rollbackResource = resource; const resourceKind = rollbackResource.kind; async function performRollback(toRevision) { const result = await rollbackResource.rollback(toRevision); if (!result.success) { throw new Error(result.message); } return result; } function handleConfirm(toRevision) { const itemName = rollbackResource.metadata.name; dispatch(clusterAction(() => performRollback(toRevision), { startMessage: t('Rolling back {{ itemName }} to previous version…', { itemName }), cancelledMessage: t('Cancelled rollback of {{ itemName }}.', { itemName }), successMessage: t('Rolled back {{ itemName }} to previous version.', { itemName }), errorMessage: t('Failed to rollback {{ itemName }}.', { itemName }), cancelUrl: location.pathname, startUrl: rollbackResource.getDetailsLink(), errorUrl: rollbackResource.getDetailsLink(), })); setOpenDialog(false); // Dispatch event for plugins/tracking dispatchRollbackEvent({ resource: rollbackResource, status: EventStatus.CONFIRMED, }); if (afterConfirm) { afterConfirm(); } } return (_jsxs(AuthVisible, { item: item, authVerb: "update", onError: (err) => { console.error(`Error while getting authorization for rollback button in ${item}:`, err); }, children: [_jsx(ActionButton, { description: t('translation|Rollback'), buttonStyle: buttonStyle, onClick: () => { setOpenDialog(true); }, icon: "mdi:undo-variant" }), _jsx(RollbackDialog, { open: openDialog, resourceKind: resourceKind, resourceName: rollbackResource.metadata.name, getRevisionHistory: getRevisionHistory, onClose: () => setOpenDialog(false), onConfirm: handleConfirm })] })); } export default RollbackButton;