@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
72 lines (71 loc) • 3.88 kB
JavaScript
import { jsx as _jsx } 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 { Icon } from '@iconify/react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useSelectedClusters } from '../../lib/k8s';
import { Activity } from '../activity/Activity';
import ActionButton from '../common/ActionButton';
import { AuthVisible } from '../common/Resource';
import { EditorDialog } from '../common/Resource';
import { parseEditorObject, RESOURCE_DEFINITIONS } from './Resource/CreateButton';
/** Inner component rendered inside the Activity panel. Holds shared state so the
* form can update the editor YAML in-place without relaunching the activity. */
function CreateResourceActivityContent(props) {
const { resourceClass, name, onClose } = props;
const { t } = useTranslation(['glossary', 'translation']);
const initialItem = React.useMemo(() => resourceClass.getBaseObject(), [resourceClass]);
const [item, setItem] = React.useState(initialItem);
const [formResource, setFormResource] = React.useState(initialItem);
const [errorMessage, setErrorMessage] = React.useState('');
const handleFormChange = (newItem) => {
setFormResource(newItem);
setItem(newItem);
};
const handleEditorChanged = (newValue) => {
setErrorMessage('');
const parsed = parseEditorObject(newValue);
if (parsed !== null) {
setFormResource(parsed);
}
};
const FormComponent = resourceClass.kind in RESOURCE_DEFINITIONS
? RESOURCE_DEFINITIONS[resourceClass.kind].form
: undefined;
return (_jsx(EditorDialog, { noDialog: true, item: item, open: true, setOpen: () => { }, onClose: onClose, saveLabel: t('translation|Apply'), errorMessage: errorMessage, onEditorChanged: handleEditorChanged, treatItemChangesAsEdits: true, title: t('translation|Create {{ name }}', { name }), "aria-label": t('translation|Create {{ name }}', { name }), formContent: FormComponent ? (_jsx(FormComponent, { resource: formResource, onChange: handleFormChange })) : undefined }));
}
/** Action button that opens an Activity panel with an EditorDialog for
* creating a Kubernetes resource. Shows a form tab when the resource kind
* has a matching entry in {@link RESOURCE_DEFINITIONS}. */
export function CreateResourceButton(props) {
const { resourceClass, resourceName } = props;
const { t } = useTranslation(['glossary', 'translation']);
const clusters = useSelectedClusters();
const name = resourceName ?? resourceClass.kind;
const activityId = 'create-resource-' + resourceClass.apiName;
const openActivity = () => {
Activity.launch({
id: activityId,
title: t('translation|Create {{ name }}', { name }),
location: 'full',
cluster: clusters[0],
icon: _jsx(Icon, { icon: "mdi:plus-circle" }),
content: (_jsx(CreateResourceActivityContent, { resourceClass: resourceClass, name: name, onClose: () => Activity.close(activityId) })),
});
};
return (_jsx(AuthVisible, { item: resourceClass, authVerb: "create", children: _jsx(ActionButton, { color: "primary", description: t('translation|Create {{ name }}', { name }), icon: 'mdi:plus-circle', onClick: openActivity }) }));
}