Skip to content

Commit 7e51121

Browse files
committed
Import modal - respect display_repositories, hide selector when no choices (ansible#4458)
* Import modal - respect display_repositories, hide selector when there are no choices No-Issue * tests (cherry picked from commit 9c8e101)
1 parent 347630c commit 7e51121

File tree

2 files changed

+92
-43
lines changed

2 files changed

+92
-43
lines changed

src/components/import-modal/import-modal.tsx

+89-40
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { t } from '@lingui/macro';
2-
import { Button, Modal, Radio } from '@patternfly/react-core';
2+
import {
3+
Button,
4+
Flex,
5+
FlexItem,
6+
Label,
7+
Modal,
8+
Radio,
9+
} from '@patternfly/react-core';
310
import { FolderOpenIcon, SpinnerIcon } from '@patternfly/react-icons';
411
import axios from 'axios';
512
import cx from 'classnames';
@@ -14,9 +21,11 @@ import {
1421
import {
1522
AlertList,
1623
AlertType,
24+
LabelGroup,
1725
MultipleRepoSelector,
1826
closeAlertMixin,
1927
} from 'src/components';
28+
import { AppContext } from 'src/loaders/app-context';
2029
import { repositoryBasePath } from 'src/utilities';
2130
import './import-modal.scss';
2231

@@ -44,9 +53,12 @@ interface IState {
4453
alerts: AlertType[];
4554
selectedRepos: AnsibleRepositoryType[]; // 0 or 1 repos
4655
onlyStaging: boolean;
56+
hideSelector: boolean;
4757
}
4858

4959
export class ImportModal extends React.Component<IProps, IState> {
60+
static contextType = AppContext;
61+
5062
acceptedFileTypes = ['application/x-gzip', 'application/gzip'];
5163
cancelToken: ReturnType<typeof CollectionAPI.getCancelToken>;
5264
COLLECTION_NAME_REGEX = /[0-9a-z_]+-[0-9a-z_]+-[0-9A-Za-z.+-]+/;
@@ -64,18 +76,19 @@ export class ImportModal extends React.Component<IProps, IState> {
6476
alerts: [],
6577
selectedRepos: [],
6678
onlyStaging: true,
79+
hideSelector: false,
6780
};
6881
}
6982

7083
componentDidMount() {
7184
this.loadAllRepos();
7285
}
7386

74-
private async loadAllRepos() {
87+
private loadAllRepos() {
7588
const { onlyStaging } = this.state;
7689

77-
const staging = onlyStaging
78-
? await AnsibleRepositoryAPI.list({
90+
const stagingByName = onlyStaging
91+
? AnsibleRepositoryAPI.list({
7992
name: 'staging',
8093
page_size: 1,
8194
pulp_label_select: 'pipeline=staging',
@@ -84,18 +97,32 @@ export class ImportModal extends React.Component<IProps, IState> {
8497
.catch(() => null)
8598
: null;
8699

87-
return AnsibleRepositoryAPI.list({
100+
const byPipeline = AnsibleRepositoryAPI.list({
88101
pulp_label_select: onlyStaging ? 'pipeline=staging' : '!pipeline',
89102
page_size: 1,
90-
})
91-
.then(({ data: { count, results } }) =>
92-
this.setState({
93-
selectedRepos: onlyStaging
103+
});
104+
105+
return Promise.all([byPipeline, stagingByName])
106+
.then(
107+
([
108+
{
109+
data: { count, results },
110+
},
111+
staging,
112+
]) => {
113+
// only staging: preselect "staging", or first repo if not found
114+
// all repos: preselect first repo only if there are no other choices
115+
const selectedRepos = onlyStaging
94116
? [staging || results[0]].filter(Boolean)
95117
: count === 1
96118
? [results[0]]
97-
: [],
98-
}),
119+
: [];
120+
121+
this.setState({
122+
selectedRepos,
123+
hideSelector: selectedRepos.length && count < 2,
124+
});
125+
},
99126
)
100127
.catch((error) =>
101128
this.addAlert(t`Error loading repositories.`, 'danger', error?.message),
@@ -125,15 +152,18 @@ export class ImportModal extends React.Component<IProps, IState> {
125152
}
126153

127154
render() {
128-
const { isOpen, collection } = this.props;
155+
const { collection, namespace, isOpen } = this.props;
129156
const {
130-
errors,
131157
errorVariant,
158+
errors,
132159
file,
160+
hideSelector,
133161
onlyStaging,
162+
selectedRepos,
134163
uploadProgress,
135164
uploadStatus,
136165
} = this.state;
166+
const { featureFlags } = this.context;
137167

138168
const skipError = () => {
139169
if (errorVariant === 'skippable') {
@@ -145,7 +175,9 @@ export class ImportModal extends React.Component<IProps, IState> {
145175
<Modal
146176
variant={'large'}
147177
title={
148-
collection ? t`New version of ${collection.name}` : t`New collection`
178+
collection
179+
? t`New version of ${namespace}.${collection.name}`
180+
: t`New collection`
149181
}
150182
isOpen={isOpen}
151183
onClose={() => this.handleClose()}
@@ -209,37 +241,54 @@ export class ImportModal extends React.Component<IProps, IState> {
209241
) : null}
210242
</div>
211243

212-
<>
213-
<br />
214-
<Radio
215-
isChecked={this.state.onlyStaging}
216-
name='radio-1'
217-
onChange={(val) => {
218-
this.setState({ onlyStaging: val }, () => this.loadAllRepos());
219-
}}
220-
label={t`Staging Repos`}
221-
id='radio-staging'
222-
></Radio>
223-
<Radio
224-
isChecked={!this.state.onlyStaging}
225-
name='radio-2'
226-
onChange={(val) => {
227-
this.setState({ onlyStaging: !val }, () => this.loadAllRepos());
228-
}}
229-
label={t`All Repos`}
230-
id='radio-all'
231-
></Radio>
232-
{!this.state.onlyStaging && (
233-
<>{t`Please note that these repositories are not filtered by permissions. Upload may fail without the right permissions.`}</>
234-
)}
235-
244+
<div style={{ lineHeight: '1em' }}>&nbsp;</div>
245+
246+
{featureFlags.display_repositories ? (
247+
<>
248+
<Radio
249+
id='radio-staging'
250+
isChecked={onlyStaging}
251+
label={t`Staging Repos`}
252+
name='radio-staging'
253+
onChange={() =>
254+
this.setState({ onlyStaging: true }, () => this.loadAllRepos())
255+
}
256+
/>
257+
<Radio
258+
id='radio-all'
259+
isChecked={!onlyStaging}
260+
label={t`All Repos`}
261+
name='radio-all'
262+
onChange={() =>
263+
this.setState({ onlyStaging: false }, () => this.loadAllRepos())
264+
}
265+
/>
266+
</>
267+
) : null}
268+
269+
{!onlyStaging && (
270+
<>{t`Please note that these repositories are not filtered by permissions. Upload may fail without the right permissions.`}</>
271+
)}
272+
273+
{hideSelector ? (
274+
<Flex>
275+
<FlexItem>
276+
<b>{t`Repository`}</b>
277+
</FlexItem>
278+
<FlexItem>
279+
<LabelGroup>
280+
<Label>{selectedRepos[0].name}</Label>
281+
</LabelGroup>
282+
</FlexItem>
283+
</Flex>
284+
) : (
236285
<MultipleRepoSelector
237286
addAlert={(a) => this.addAlertObj(a)}
238287
params={{
239288
pulp_label_select: onlyStaging ? 'pipeline=staging' : '!pipeline',
240289
}}
241290
singleSelectionOnly={true}
242-
selectedRepos={this.state.selectedRepos}
291+
selectedRepos={selectedRepos}
243292
setSelectedRepos={(selectedRepos) =>
244293
this.setState({
245294
selectedRepos,
@@ -248,7 +297,7 @@ export class ImportModal extends React.Component<IProps, IState> {
248297
})
249298
}
250299
/>
251-
</>
300+
)}
252301
</Modal>
253302
);
254303
}

test/cypress/e2e/collections/collection_upload.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ describe('Collection Upload Tests', () => {
4949
);
5050
cy.contains('testcollection');
5151
cy.contains('Upload new version').click();
52-
cy.contains('New version of testcollection');
52+
cy.contains('New version of testspace.testcollection');
5353

5454
cy.visit(
5555
`${uiPrefix}collections?page_size=10&view_type=card&keywords=testcollection`,
5656
);
5757
cy.contains('testcollection');
5858
cy.get('button[aria-label="Actions"]').click();
5959
cy.contains('Upload new version').click();
60-
cy.contains('New version of testcollection');
60+
cy.contains('New version of testspace.testcollection');
6161
});
6262

6363
it('should see upload new collection version in collection detail when user does have permissions', () => {
@@ -66,7 +66,7 @@ describe('Collection Upload Tests', () => {
6666
cy.contains('testcollection');
6767
cy.get('[data-cy="kebab-toggle"] button[aria-label="Actions"]').click();
6868
cy.contains('Upload new version').click();
69-
cy.contains('New version of testcollection');
69+
cy.contains('New version of testspace.testcollection');
7070
});
7171

7272
it('user should not be able to upload new collection without permissions', () => {

0 commit comments

Comments
 (0)