1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 15:21:13 +03:00

start on InventoriesLookup

This commit is contained in:
Keith Grant 2019-07-17 09:25:40 -07:00
parent d9c2bd8ef3
commit c080346751
9 changed files with 144 additions and 10 deletions

View File

@ -1,5 +1,6 @@
import Config from './models/Config';
import InstanceGroups from './models/InstanceGroups';
import Inventories from './models/Inventories';
import JobTemplates from './models/JobTemplates';
import Jobs from './models/Jobs';
import Me from './models/Me';
@ -13,6 +14,7 @@ import WorkflowJobTemplates from './models/WorkflowJobTemplates';
const ConfigAPI = new Config();
const InstanceGroupsAPI = new InstanceGroups();
const InventoriesAPI = new Inventories();
const JobTemplatesAPI = new JobTemplates();
const JobsAPI = new Jobs();
const MeAPI = new Me();
@ -27,6 +29,7 @@ const WorkflowJobTemplatesAPI = new WorkflowJobTemplates();
export {
ConfigAPI,
InstanceGroupsAPI,
InventoriesAPI,
JobTemplatesAPI,
JobsAPI,
MeAPI,

View File

@ -0,0 +1,10 @@
import Base from '../Base';
class Inventories extends Base {
constructor(http) {
super(http);
this.baseUrl = '/api/v2/inventories/';
}
}
export default Inventories;

View File

@ -155,11 +155,6 @@
// and bem style, as well as moved into component-based scss files
//
.awx-lookup .pf-c-form-control {
--pf-c-form-control--Height: 90px;
overflow-y: auto;
}
.at-c-listCardBody {
--pf-c-card__footer--PaddingX: 0;
--pf-c-card__footer--PaddingY: 0;

View File

@ -5,11 +5,12 @@ import { SearchIcon } from '@patternfly/react-icons';
import {
Button,
ButtonVariant,
InputGroup,
InputGroup as PFInputGroup,
Modal,
} from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import styled from 'styled-components';
import PaginatedDataList from '../PaginatedDataList';
import DataListToolbar from '../DataListToolbar';
@ -18,6 +19,13 @@ import SelectedList from '../SelectedList';
import { ChipGroup, Chip } from '../Chip';
import { getQSConfig, parseNamespacedQueryString } from '../../util/qs';
const InputGroup = styled(PFInputGroup)`
${props => props.multiple && (`
--pf-c-form-control--Height: 90px;
overflow-y: auto;
`)}
`;
class Lookup extends React.Component {
constructor(props) {
super(props);
@ -145,7 +153,7 @@ class Lookup extends React.Component {
return (
<Fragment>
<InputGroup className="awx-lookup">
<InputGroup>
<Button
aria-label="Search"
id={id}
@ -220,12 +228,14 @@ Lookup.propTypes = {
onLookupSave: PropTypes.func.isRequired,
value: PropTypes.arrayOf(PropTypes.object).isRequired,
sortedColumnKey: PropTypes.string.isRequired,
multiple: PropTypes.bool,
};
Lookup.defaultProps = {
id: 'lookup-search',
lookupHeader: null,
name: null,
multiple: false,
};
export { Lookup as _Lookup };

View File

@ -35,6 +35,7 @@ class InstanceGroupsLookup extends React.Component {
value={value}
onLookupSave={onChange}
getItems={getInstanceGroups}
multiple
columns={[
{ name: i18n._(t`Name`), key: 'name', isSortable: true },
{

View File

@ -0,0 +1,71 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { FormGroup, Tooltip } from '@patternfly/react-core';
import { QuestionCircleIcon } from '@patternfly/react-icons';
import { InventoriesAPI } from '@api';
import Lookup from '@components/Lookup';
const getInventories = async params => InventoriesAPI.read(params);
class InventoriesLookup extends React.Component {
render() {
const { value, tooltip, onChange, i18n } = this.props;
return (
<FormGroup
label={
<Fragment>
{i18n._(t`Inventories`)}{' '}
{tooltip && (
<Tooltip position="right" content={tooltip}>
<QuestionCircleIcon />
</Tooltip>
)}
</Fragment>
}
fieldId="inventories-lookup"
>
<Lookup
id="inventories-lookup"
lookupHeader={i18n._(t`Inventories`)}
name="inventories"
value={value}
onLookupSave={onChange}
getItems={getInventories}
multiple
columns={[
{ name: i18n._(t`Name`), key: 'name', isSortable: true },
{
name: i18n._(t`Modified`),
key: 'modified',
isSortable: false,
isNumeric: true,
},
{
name: i18n._(t`Created`),
key: 'created',
isSortable: false,
isNumeric: true,
},
]}
sortedColumnKey="name"
/>
</FormGroup>
);
}
}
InventoriesLookup.propTypes = {
value: PropTypes.arrayOf(PropTypes.object).isRequired,
tooltip: PropTypes.string,
onChange: PropTypes.func.isRequired,
};
InventoriesLookup.defaultProps = {
tooltip: '',
};
export default withI18n()(InventoriesLookup);

View File

@ -10,6 +10,7 @@ import AnsibleSelect from '@components/AnsibleSelect';
import FormActionGroup from '@components/FormActionGroup';
import FormField from '@components/FormField';
import FormRow from '@components/FormRow';
import Lookup from '@components/Lookup';
import { required } from '@util/validators';
import styled from 'styled-components';
import { JobTemplate } from '@types';
@ -105,7 +106,37 @@ class JobTemplateForm extends Component {
</FormGroup>
)}
/>
<FormField
<Field
name="inventory"
validate={required(null, i18n)}
render={({ field, form }) => (
<FormGroup
fieldId="template-inventory"
helperTextInvalid={form.errors.inventory}
isRequired
label={i18n._(t`Inventory`)}
>
<Lookup
id="template-inventory"
lookupHeader={i18n._(t`Inventory`)}
name="inventory"
value={[field.value]}
onLookupSave={(value) => {console.log(value)}}
getItems={() => ({
data: {
results: [{id: 1, name: 'foo'}],
count: 1
}
})}
columns={[
{ name: i18n._(t`Name`), key: 'name', isSortable: true},
]}
sortedColumnsKey="name"
/>
</FormGroup>
)}
/>
{/* <FormField
id="template-inventory"
name="inventory"
type="number"
@ -114,7 +145,7 @@ class JobTemplateForm extends Component {
you want this job to manage.`)}
isRequired
validate={required(null, i18n)}
/>
/> */}
<FormField
id="template-project"
name="project"

View File

@ -1,7 +1,16 @@
// TODO: switch to using Lingui i18n for pluralization
export function pluralize(str) {
return str[str.length - 1] === 's' ? `${str}es` : `${str}s`;
const lastChar = str[str.length - 1];
if (lastChar === 's') {
return `${str}es`
}
if (lastChar === 'y') {
return `${str.substr(0, str.length - 1)}ies`;
}
return `${str}s`;
}
// TODO: switch to using Lingui i18n for articles
export function getArticle(str) {
const first = str[0];
if ('aeiou'.includes(first)) {

View File

@ -9,6 +9,10 @@ describe('string utils', () => {
test('should add an "es"', () => {
expect(pluralize('class')).toEqual('classes');
});
test('should handle word ending in y', () => {
expect(pluralize('inventory')).toEqual('inventories');
});
});
describe('getArticle', () => {