mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 02:19:58 -03:30
disables prompt on launch checkbox
This commit is contained in:
parent
fc4060778b
commit
b51f013880
@ -23,6 +23,7 @@ function FieldWithPrompt({
|
||||
promptId,
|
||||
promptName,
|
||||
tooltip,
|
||||
isDisabled,
|
||||
}) {
|
||||
return (
|
||||
<div className="pf-c-form__group">
|
||||
@ -39,6 +40,7 @@ function FieldWithPrompt({
|
||||
{tooltip && <FieldTooltip content={tooltip} />}
|
||||
</div>
|
||||
<StyledCheckboxField
|
||||
isDisabled={isDisabled}
|
||||
id={promptId}
|
||||
label={i18n._(t`Prompt on launch`)}
|
||||
name={promptName}
|
||||
|
||||
@ -9,10 +9,19 @@ const QuestionCircleIcon = styled(PFQuestionCircleIcon)`
|
||||
margin-left: 10px;
|
||||
`;
|
||||
|
||||
function CheckboxField({ id, name, label, tooltip, validate, ...rest }) {
|
||||
function CheckboxField({
|
||||
id,
|
||||
name,
|
||||
label,
|
||||
tooltip,
|
||||
validate,
|
||||
isDisabled,
|
||||
...rest
|
||||
}) {
|
||||
const [field] = useField({ name, validate });
|
||||
return (
|
||||
<Checkbox
|
||||
isDisabled={isDisabled}
|
||||
aria-label={label}
|
||||
label={
|
||||
<span>
|
||||
|
||||
@ -33,6 +33,7 @@ function CredentialLookup({
|
||||
history,
|
||||
i18n,
|
||||
tooltip,
|
||||
isDisabled,
|
||||
}) {
|
||||
const {
|
||||
result: { count, credentials, relatedSearchableKeys, searchableKeys },
|
||||
@ -108,6 +109,7 @@ function CredentialLookup({
|
||||
onChange={onChange}
|
||||
required={required}
|
||||
qsConfig={QS_CONFIG}
|
||||
isDisabled={isDisabled}
|
||||
renderOptionsList={({ state, dispatch, canDelete }) => (
|
||||
<OptionsList
|
||||
value={state.selectedItems}
|
||||
|
||||
@ -10,6 +10,7 @@ import OptionsList from '../OptionsList';
|
||||
import useRequest from '../../util/useRequest';
|
||||
import { getQSConfig, parseQueryString } from '../../util/qs';
|
||||
import LookupErrorMessage from './shared/LookupErrorMessage';
|
||||
import FieldWithPrompt from '../FieldWithPrompt';
|
||||
|
||||
const QS_CONFIG = getQSConfig('inventory', {
|
||||
page: 1,
|
||||
@ -17,7 +18,18 @@ const QS_CONFIG = getQSConfig('inventory', {
|
||||
order_by: 'name',
|
||||
});
|
||||
|
||||
function InventoryLookup({ value, onChange, onBlur, required, i18n, history }) {
|
||||
function InventoryLookup({
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
i18n,
|
||||
history,
|
||||
required,
|
||||
isPromptableField,
|
||||
fieldId,
|
||||
promptId,
|
||||
promptName,
|
||||
}) {
|
||||
const {
|
||||
result: {
|
||||
inventories,
|
||||
@ -61,7 +73,70 @@ function InventoryLookup({ value, onChange, onBlur, required, i18n, history }) {
|
||||
fetchInventories();
|
||||
}, [fetchInventories]);
|
||||
|
||||
return (
|
||||
return isPromptableField ? (
|
||||
<>
|
||||
<FieldWithPrompt
|
||||
fieldId={fieldId}
|
||||
isRequired={required}
|
||||
label={i18n._(t`Inventory`)}
|
||||
promptId={promptId}
|
||||
promptName={promptName}
|
||||
isDisabled={!canEdit}
|
||||
tooltip={i18n._(t`Select the inventory containing the hosts
|
||||
you want this job to manage.`)}
|
||||
>
|
||||
<Lookup
|
||||
id="inventory-lookup"
|
||||
header={i18n._(t`Inventory`)}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
required={required}
|
||||
isLoading={isLoading}
|
||||
isDisabled={!canEdit}
|
||||
qsConfig={QS_CONFIG}
|
||||
renderOptionsList={({ state, dispatch, canDelete }) => (
|
||||
<OptionsList
|
||||
value={state.selectedItems}
|
||||
options={inventories}
|
||||
optionCount={count}
|
||||
searchColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
key: 'name__icontains',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Created By (Username)`),
|
||||
key: 'created_by__username__icontains',
|
||||
},
|
||||
{
|
||||
name: i18n._(t`Modified By (Username)`),
|
||||
key: 'modified_by__username__icontains',
|
||||
},
|
||||
]}
|
||||
sortColumns={[
|
||||
{
|
||||
name: i18n._(t`Name`),
|
||||
key: 'name',
|
||||
},
|
||||
]}
|
||||
searchableKeys={searchableKeys}
|
||||
relatedSearchableKeys={relatedSearchableKeys}
|
||||
multiple={state.multiple}
|
||||
header={i18n._(t`Inventory`)}
|
||||
name="inventory"
|
||||
qsConfig={QS_CONFIG}
|
||||
readOnly={!canDelete}
|
||||
selectItem={item => dispatch({ type: 'SELECT_ITEM', item })}
|
||||
deselectItem={item => dispatch({ type: 'DESELECT_ITEM', item })}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<LookupErrorMessage error={error} />
|
||||
</FieldWithPrompt>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Lookup
|
||||
id="inventory-lookup"
|
||||
|
||||
@ -91,7 +91,8 @@ function Lookup(props) {
|
||||
};
|
||||
|
||||
const { isModalOpen, selectedItems } = state;
|
||||
const canDelete = !required || (multiple && value.length > 1);
|
||||
const canDelete =
|
||||
(!required || (multiple && value.length > 1)) && !isDisabled;
|
||||
let items = [];
|
||||
if (multiple) {
|
||||
items = value;
|
||||
@ -110,11 +111,7 @@ function Lookup(props) {
|
||||
>
|
||||
<SearchIcon />
|
||||
</Button>
|
||||
<ChipHolder
|
||||
isDisabled={isDisabled}
|
||||
// css="background-color: #d2d2d2"
|
||||
className="pf-c-form-control"
|
||||
>
|
||||
<ChipHolder isDisabled={isDisabled} className="pf-c-form-control">
|
||||
<ChipGroup numChips={5} totalChips={items.length}>
|
||||
{items.map(item =>
|
||||
renderItemChip({
|
||||
|
||||
@ -12,6 +12,7 @@ import {
|
||||
JobTemplatesAPI,
|
||||
LabelsAPI,
|
||||
ProjectsAPI,
|
||||
InventoriesAPI,
|
||||
} from '../../../api';
|
||||
import JobTemplateEdit from './JobTemplateEdit';
|
||||
|
||||
@ -181,6 +182,12 @@ JobTemplatesAPI.readCredentials.mockResolvedValue({
|
||||
ProjectsAPI.readPlaybooks.mockResolvedValue({
|
||||
data: mockRelatedProjectPlaybooks,
|
||||
});
|
||||
InventoriesAPI.readOptions.mockResolvedValue({
|
||||
data: { actions: { GET: {}, POST: {} } },
|
||||
});
|
||||
ProjectsAPI.readOptions.mockResolvedValue({
|
||||
data: { actions: { GET: {}, POST: {} } },
|
||||
});
|
||||
LabelsAPI.read.mockResolvedValue({ data: { results: [] } });
|
||||
CredentialsAPI.read.mockResolvedValue({
|
||||
data: {
|
||||
|
||||
@ -234,17 +234,15 @@ function JobTemplateForm({
|
||||
}}
|
||||
/>
|
||||
</FieldWithPrompt>
|
||||
<FieldWithPrompt
|
||||
fieldId="template-inventory"
|
||||
isRequired={!askInventoryOnLaunchField.value}
|
||||
label={i18n._(t`Inventory`)}
|
||||
promptId="template-ask-inventory-on-launch"
|
||||
promptName="ask_inventory_on_launch"
|
||||
tooltip={i18n._(t`Select the inventory containing the hosts
|
||||
you want this job to manage.`)}
|
||||
>
|
||||
<>
|
||||
<InventoryLookup
|
||||
value={inventory}
|
||||
fieldId="template-inventory"
|
||||
promptId="template-ask-inventory-on-launch"
|
||||
promptName="ask_inventory_on_launch"
|
||||
isPromptableField
|
||||
tooltip={i18n._(t`Select the inventory containing the hosts
|
||||
you want this job to manage.`)}
|
||||
onBlur={() => inventoryHelpers.setTouched()}
|
||||
onChange={value => {
|
||||
inventoryHelpers.setValue(value ? value.id : null);
|
||||
@ -263,7 +261,7 @@ function JobTemplateForm({
|
||||
{inventoryMeta.error}
|
||||
</div>
|
||||
)}
|
||||
</FieldWithPrompt>
|
||||
</>
|
||||
<ProjectLookup
|
||||
value={projectField.value}
|
||||
onBlur={() => projectHelpers.setTouched()}
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
ProjectsAPI,
|
||||
CredentialsAPI,
|
||||
CredentialTypesAPI,
|
||||
InventoriesAPI,
|
||||
} from '../../../api';
|
||||
|
||||
jest.mock('../../../api');
|
||||
@ -111,14 +112,23 @@ describe('<JobTemplateForm />', () => {
|
||||
JobTemplatesAPI.updateWebhookKey.mockReturnValue({
|
||||
data: { webhook_key: 'webhook key' },
|
||||
});
|
||||
ProjectsAPI.readPlaybooks.mockReturnValue({
|
||||
data: ['debug.yml'],
|
||||
JobTemplatesAPI.updateWebhookKey.mockReturnValue({
|
||||
data: { webhook_key: 'webhook key' },
|
||||
});
|
||||
ProjectsAPI.readDetail.mockReturnValue({
|
||||
name: 'foo',
|
||||
id: 1,
|
||||
allow_override: true,
|
||||
});
|
||||
ProjectsAPI.readPlaybooks.mockReturnValue({
|
||||
data: ['debug.yml'],
|
||||
});
|
||||
InventoriesAPI.readOptions.mockResolvedValue({
|
||||
data: { actions: { GET: {}, POST: {} } },
|
||||
});
|
||||
ProjectsAPI.readOptions.mockResolvedValue({
|
||||
data: { actions: { GET: {}, POST: {} } },
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@ -35,7 +35,7 @@ function PlaybookSelect({ projectId, isValid, field, onBlur, onError, i18n }) {
|
||||
});
|
||||
return opts;
|
||||
}, [projectId, i18n]),
|
||||
[field.value]
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -110,23 +110,21 @@ function WorkflowJobTemplateForm({
|
||||
value={organizationField.value}
|
||||
isValid={!organizationMeta.error}
|
||||
/>
|
||||
|
||||
<FieldWithPrompt
|
||||
fieldId="wfjt-inventory"
|
||||
label={i18n._(t`Inventory`)}
|
||||
promptId="wfjt-ask-inventory-on-launch"
|
||||
promptName="ask_inventory_on_launch"
|
||||
tooltip={i18n._(
|
||||
t`Select an inventory for the workflow. This inventory is applied to all job template nodes that prompt for an inventory.`
|
||||
)}
|
||||
>
|
||||
<>
|
||||
<InventoryLookup
|
||||
promptId="wfjt-ask-inventory-on-launch"
|
||||
promptName="ask_inventory_on_launch"
|
||||
tooltip={i18n._(
|
||||
t`Select an inventory for the workflow. This inventory is applied to all job template nodes that prompt for an inventory.`
|
||||
)}
|
||||
fieldId="wfjt-inventory"
|
||||
isPromptableField
|
||||
value={inventoryField.value}
|
||||
onBlur={() => inventoryHelpers.setTouched()}
|
||||
onChange={value => {
|
||||
inventoryHelpers.setValue(value);
|
||||
}}
|
||||
required={askInventoryOnLaunchField.value}
|
||||
required={!askInventoryOnLaunchField.value}
|
||||
touched={inventoryMeta.touched}
|
||||
error={inventoryMeta.error}
|
||||
/>
|
||||
@ -139,8 +137,7 @@ function WorkflowJobTemplateForm({
|
||||
{inventoryMeta.error}
|
||||
</div>
|
||||
)}
|
||||
</FieldWithPrompt>
|
||||
|
||||
</>
|
||||
<FieldWithPrompt
|
||||
fieldId="wjft-limit"
|
||||
label={i18n._(t`Limit`)}
|
||||
|
||||
@ -11,6 +11,8 @@ import {
|
||||
LabelsAPI,
|
||||
OrganizationsAPI,
|
||||
InventoriesAPI,
|
||||
ProjectsAPI,
|
||||
CredentialTypesAPI,
|
||||
} from '../../../api';
|
||||
|
||||
jest.mock('../../../api/models/CredentialTypes');
|
||||
@ -18,6 +20,8 @@ jest.mock('../../../api/models/WorkflowJobTemplates');
|
||||
jest.mock('../../../api/models/Labels');
|
||||
jest.mock('../../../api/models/Organizations');
|
||||
jest.mock('../../../api/models/Inventories');
|
||||
jest.mock('../../../api/models/Projects');
|
||||
jest.mock('../../../api/models/Credentials');
|
||||
|
||||
describe('<WorkflowJobTemplateForm/>', () => {
|
||||
let wrapper;
|
||||
@ -71,6 +75,15 @@ describe('<WorkflowJobTemplateForm/>', () => {
|
||||
{ id: 2, name: 'Bar' },
|
||||
],
|
||||
});
|
||||
CredentialTypesAPI.read.mockResolvedValue({
|
||||
data: { results: [{ id: 1 }] },
|
||||
});
|
||||
InventoriesAPI.readOptions.mockResolvedValue({
|
||||
data: { actions: { GET: {}, POST: {} } },
|
||||
});
|
||||
ProjectsAPI.readOptions.mockResolvedValue({
|
||||
data: { actions: { GET: {}, POST: {} } },
|
||||
});
|
||||
|
||||
history = createMemoryHistory({
|
||||
initialEntries: ['/templates/workflow_job_template/6/edit'],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user