disables prompt on launch checkbox

This commit is contained in:
Alex Corey 2020-09-03 11:14:15 -04:00
parent fc4060778b
commit b51f013880
11 changed files with 145 additions and 35 deletions

View File

@ -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}

View File

@ -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>

View File

@ -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}

View File

@ -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"

View File

@ -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({

View File

@ -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: {

View File

@ -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()}

View File

@ -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(() => {

View File

@ -35,7 +35,7 @@ function PlaybookSelect({ projectId, isValid, field, onBlur, onError, i18n }) {
});
return opts;
}, [projectId, i18n]),
[field.value]
[]
);
useEffect(() => {

View File

@ -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`)}

View File

@ -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'],