Skip to content

Commit

Permalink
Fixes #36679 - Sort CV versions when adding component views
Browse files Browse the repository at this point in the history
  • Loading branch information
sjha4 committed Aug 15, 2023
1 parent 8e5ffdd commit 5579a53
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 256 deletions.
4 changes: 4 additions & 0 deletions app/models/katello/content_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ def components
content_view_components.map(&:latest_version).compact.freeze
end

def sorted_versions
versions.order('created_at DESC')
end

# Adds content view components based on the input
# [{:content_view_version_id=>1, :latest=> false}, {:content_view_id=>1, :latest=> true} ..]
def add_components(components_to_add)
Expand Down
2 changes: 1 addition & 1 deletion app/models/katello/content_view_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def latest_version
end

def component_content_view_versions
self.content_view&.versions
self.content_view&.versions&.order(created_at: :desc)
end

private
Expand Down
2 changes: 1 addition & 1 deletion app/views/katello/api/v2/content_views/base.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ else
attributes :repository_ids
end

child :versions => :versions do
child :sorted_versions => :versions do
attributes :id, :version
attributes :created_at => :published
attributes :description
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useMemo } from 'react';
import PropTypes from 'prop-types';
import {
Flex, Modal, ModalVariant, Select, SelectVariant,
Expand All @@ -12,13 +12,12 @@ import { STATUS } from 'foremanReact/constants';
import {
selectCVDetails,
selectCVDetailStatus,
selectCVDetailError,
} from '../../Details/ContentViewDetailSelectors';
import { addComponent } from '../ContentViewDetailActions';
import { CONTENT_VIEW_NEEDS_PUBLISH } from '../../ContentViewsConstants';

const ComponentContentViewAddModal = ({
cvId, componentCvId, componentId, latest, show, setIsOpen,
cvId, componentCvId, componentId, latest, componentVersionId, show, setIsOpen,
}) => {
const dispatch = useDispatch();
const componentDetails = useSelector(
Expand All @@ -29,29 +28,20 @@ const ComponentContentViewAddModal = ({
state => selectCVDetailStatus(state, componentCvId),
shallowEqual,
);
const componentError = useSelector(
state => selectCVDetailError(state, componentCvId),
shallowEqual,
);
const [cvName, setCvName] = useState('');
const [options, setOptions] = useState([]);
const cvName = componentDetails?.name ?? '';
const options = useMemo(() => (componentDetails?.versions ?? []).map(item => ({
value: item.id, label: __(`Version ${item.version}`), description: item.description, publishedAtWords: __(` (${item.published_at_words} ago)`),
})), [componentDetails?.versions]);
const [formLatest, setFormLatest] = useState(componentId ? latest : false);
const [selected, setSelected] = useState(null);
const [prevOptions, setPrevOptions] = useState(options);
const [cvVersionSelectOpen, setCvVersionSelectOpen] = useState(false);
const versionsLoading = componentStatus === STATUS.PENDING;

useEffect(() => {
if (!versionsLoading && componentDetails) {
const { name, versions } = componentDetails;
const versionMutable = versions;
setCvName(name);
const opt = versionMutable.map(item => ({
value: item.id, label: __(`Version ${item.version}`), description: item.description, publishedAtWords: __(` (${item.published_at_words} ago)`),
}));
setOptions([...opt].reverse());
setSelected(opt.slice(-1)[0].value);
}
}, [componentDetails, componentStatus, componentError, versionsLoading]);
if (options !== prevOptions) {
setPrevOptions(options);
setSelected(componentVersionId ?? options[0]?.value);
}

const getAddParams = () => {
if (formLatest) {
Expand Down Expand Up @@ -175,13 +165,18 @@ ComponentContentViewAddModal.propTypes = {
PropTypes.string,
]),
latest: PropTypes.bool,
componentVersionId: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
]),
show: PropTypes.bool,
setIsOpen: PropTypes.func,
};

ComponentContentViewAddModal.defaultProps = {
componentId: null,
latest: false,
componentVersionId: null,
show: false,
setIsOpen: null,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useMemo } from 'react';
import { last } from 'lodash';
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import {
Flex, Modal, ModalVariant, Select, SelectVariant,
Expand All @@ -13,28 +12,19 @@ import { addComponent } from '../ContentViewDetailActions';

const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
const dispatch = useDispatch();
const [versionSelectOptions, setVersionSelectOptions] = useState({});
const [selectedVersion, setSelectedVersion] = useState({});
const [selectedComponentLatest, setSelectedComponentLatest] = useState({});
const versionSelect = {};
const versionSelectedOption = {};
const componentLatest = {};
rowsToAdd.forEach((row) => {
const { componentCvVersions: versions, componentCvName: name } = row;
versionSelect[name] = versions;
versionSelectedOption[name] = versions[0]?.id;
componentLatest[name] = versions && versions?.length === 0;
});
const [selectedVersion, setSelectedVersion] = useState(versionSelectedOption);
const [selectedComponentLatest, setSelectedComponentLatest] = useState(componentLatest);
const [cvVersionSelectOpen, setCvVersionSelectOpen] = useState('');


useMemo(() => {
const versionSelect = {};
const versionSelectedOption = {};
const componentLatest = {};
rowsToAdd.forEach((row) => {
const { componentCvVersions: versions, componentCvName: name } = row;
const sortedVersions = [].concat(versions).sort((a, b) => (a.id > b.id ? 1 : -1));
versionSelect[name] = sortedVersions;
versionSelectedOption[name] = last(sortedVersions)?.id;
componentLatest[name] = sortedVersions && sortedVersions?.length === 0;
});
setVersionSelectOptions(versionSelect);
setSelectedVersion(versionSelectedOption);
setSelectedComponentLatest(componentLatest);
}, [rowsToAdd, setVersionSelectOptions, setSelectedVersion, setSelectedComponentLatest]);

const bulkAddParams = () => rowsToAdd.map((row) => {
const { componentCvId: id, componentCvName: name } = row;
if (selectedComponentLatest[name]) {
Expand Down Expand Up @@ -66,7 +56,7 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
onSubmit();
}}
>
{Object.keys(versionSelectOptions).sort().map(componentCvName => (
{Object.keys(versionSelect).sort().map(componentCvName => (
<Card
ouiaId="componentCvName"
aria-label="componentCvName"
Expand All @@ -79,7 +69,7 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
variant={SelectVariant.typeahead}
selections={selectedVersion[componentCvName]}
ouiaId="select-version"
isDisabled={versionSelectOptions[componentCvName].length <= 1 ||
isDisabled={versionSelect[componentCvName].length <= 1 ||
selectedComponentLatest[componentCvName]}
onSelect={(__event, value) => {
setSelectedVersion({ ...selectedVersion, ...{ [componentCvName]: value } });
Expand All @@ -94,7 +84,7 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
menuAppendTo="parent"
maxHeight="20rem"
>
{versionSelectOptions[componentCvName].map(version => (
{versionSelect[componentCvName].map(version => (
<SelectOption
key={`${componentCvName}-${version.version}`}
aria-label={`${componentCvName}-${version.version}`}
Expand All @@ -115,11 +105,16 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
name="latest"
label={__('Always update to latest version')}
isChecked={selectedComponentLatest[componentCvName]}
onChange={checked =>
onChange={(checked) => {
setSelectedComponentLatest({
...selectedComponentLatest,
...{ [componentCvName]: checked },
})
});
setSelectedVersion({
...selectedVersion,
...{ [componentCvName]: versionSelect[componentCvName][0]?.id },
});
}
}
/>
<Tooltip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const ContentViewComponents = ({ cvId, details }) => {
const [componentCvEditing, setComponentCvEditing] = useState(null);
const [componentLatest, setComponentLatest] = useState(false);
const [componentId, setComponentId] = useState(null);
const [componentVersionId, setComponentVersionId] = useState(null);
const [selectedComponentsToAdd, setSelectedComponentsToAdd] = useState(null);
const [bulkAdding, setBulkAdding] = useState(false);
const [bulkActionOpen, setBulkActionOpen] = useState(false);
Expand Down Expand Up @@ -86,6 +87,11 @@ const ContentViewComponents = ({ cvId, details }) => {
setVersionEditing(true);
setCompositeCvEditing(cvId);
setComponentCvEditing(componentCvId);
if (added) {
setComponentVersionId(published?.id);
} else {
setComponentVersionId(null);
}
setComponentLatest(latest);
setComponentId(added);
} else { // if no versions are present, default to always latest and add cv without modal
Expand Down Expand Up @@ -297,6 +303,7 @@ const ContentViewComponents = ({ cvId, details }) => {
componentCvId={componentCvEditing}
componentId={componentId}
latest={componentLatest}
componentVersionId={componentVersionId}
show={versionEditing}
setIsOpen={setVersionEditing}
aria-label="edit_component_modal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@
},
"component_content_view_versions": [
{
"id": 36,
"version": "1.0",
"description": "Version 1.0",
"published_at_words": "5 days"
"id": 44,
"version": "4.0",
"description": "Version 4.0",
"published_at_words": "3 days"
},
{
"id": 42,
Expand All @@ -140,10 +140,10 @@
"published_at_words": "4 days"
},
{
"id": 44,
"version": "4.0",
"description": "Version 4.0",
"published_at_words": "3 days"
"id": 36,
"version": "1.0",
"description": "Version 1.0",
"published_at_words": "5 days"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ test('Can add published component views to content view with modal', async (done

const addComponentParams = {
compositeContentViewId: 4,
components: [{ content_view_version_id: 85 }],
components: [{ content_view_version_id: 13 }],
};

const addComponentScope = nockInstance
Expand Down
Loading

0 comments on commit 5579a53

Please sign in to comment.