diff --git a/lib/katello/plugin.rb b/lib/katello/plugin.rb index ccaaef69edb..2db0542c93c 100644 --- a/lib/katello/plugin.rb +++ b/lib/katello/plugin.rb @@ -230,6 +230,15 @@ :parent => :lab_features_menu, :turbolinks => false + menu :labs_menu, + :host_collections_lab, + :url => '/labs/host_collections', + :url_hash => {:controller => 'katello/api/v2/host_collections_controller', + :action => 'index'}, + :caption => N_('Host Collections'), + :parent => :lab_features_menu, + :turbolinks => false + extend_template_helpers Katello::KatelloUrlsHelper extend_template_helpers Katello::Concerns::BaseTemplateScopeExtensions diff --git a/webpack/components/InlineEdit/InlineEdit.scss b/webpack/components/InlineEdit/InlineEdit.scss new file mode 100644 index 00000000000..b65d9c92e4e --- /dev/null +++ b/webpack/components/InlineEdit/InlineEdit.scss @@ -0,0 +1,24 @@ +.inline-edit-display { + align-items: center; + + .inline-edit-value { + display: block; + min-height: 1.5rem; + } + + button { + visibility: hidden; + } + + &:hover button { + visibility: visible; + } +} + +.inline-edit-form { + margin-bottom: 0; + + .pf-c-form__group-control { + width: 100%; + } +} diff --git a/webpack/components/InlineEdit/index.js b/webpack/components/InlineEdit/index.js new file mode 100644 index 00000000000..190c0d714d3 --- /dev/null +++ b/webpack/components/InlineEdit/index.js @@ -0,0 +1,171 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { translate as __ } from 'foremanReact/common/I18n'; +import { + Button, + Flex, + FlexItem, + FormGroup, + FormSelect, + FormSelectOption, + TextArea, + TextInput, +} from '@patternfly/react-core'; +import { CheckIcon, TimesIcon, PencilAltIcon } from '@patternfly/react-icons'; +import './InlineEdit.scss'; + +const InlineEdit = ({ + value, onSave, isRequired, multiline, type, options, +}) => { + const [isEditing, setIsEditing] = useState(false); + const [editValue, setEditValue] = useState(value); + + const handleSave = () => { + if (isRequired && !editValue.trim()) { + return; + } + onSave(editValue); + setIsEditing(false); + }; + + const handleCancel = () => { + setEditValue(value); + setIsEditing(false); + }; + + const handleKeyDown = (e) => { + if (e.key === 'Enter' && !multiline) { + e.preventDefault(); + handleSave(); + } else if (e.key === 'Escape') { + handleCancel(); + } + }; + + const renderValue = () => { + if (type === 'select') { + const option = options.find(opt => opt.value === value); + return option?.label || value || __('Not set'); + } + return value || __('Not set'); + }; + + const renderEditField = () => { + if (type === 'select') { + return ( + setEditValue(newValue)} + aria-label="inline-edit-select" + ouiaId="inline-edit-select" + > + {options.map(option => ( + + ))} + + ); + } + + if (multiline) { + return ( +