mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 15:21:13 +03:00
add variables & artifacts to job detail
This commit is contained in:
parent
4372e977f0
commit
968cc8c79c
@ -1,4 +1,5 @@
|
|||||||
import CodeMirrorInput from './CodeMirrorInput';
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
|
|
||||||
export default CodeMirrorInput;
|
export default CodeMirrorInput;
|
||||||
|
export { default as VariablesInput } from './VariablesInput';
|
||||||
export { default as VariablesField } from './VariablesField';
|
export { default as VariablesField } from './VariablesField';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { Component, useState, useEffect } from 'react';
|
import React from 'react';
|
||||||
import { Link, withRouter } from 'react-router-dom';
|
import { Link, withRouter } from 'react-router-dom';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
@ -6,8 +6,7 @@ import { CardBody, Button } from '@patternfly/react-core';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { DetailList, Detail } from '@components/DetailList';
|
import { DetailList, Detail } from '@components/DetailList';
|
||||||
import { ChipGroup, Chip } from '@components/Chip';
|
import { ChipGroup, Chip } from '@components/Chip';
|
||||||
import ContentError from '@components/ContentError';
|
import { VariablesInput } from '@components/CodeMirrorInput';
|
||||||
import ContentLoading from '@components/ContentLoading';
|
|
||||||
import { toTitleCase } from '@util/strings';
|
import { toTitleCase } from '@util/strings';
|
||||||
|
|
||||||
const ActionButtonWrapper = styled.div`
|
const ActionButtonWrapper = styled.div`
|
||||||
@ -24,13 +23,13 @@ const VERBOSITY = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function JobDetail ({ job, i18n }) {
|
function JobDetail ({ job, i18n }) {
|
||||||
const [instanceGroups, setInstanceGroups] = useState(null);
|
|
||||||
console.log(job);
|
|
||||||
const {
|
const {
|
||||||
job_template: jobTemplate,
|
job_template: jobTemplate,
|
||||||
project,
|
project,
|
||||||
inventory,
|
inventory,
|
||||||
instance_group: instanceGroup,
|
instance_group: instanceGroup,
|
||||||
|
credentials,
|
||||||
|
labels,
|
||||||
} = job.summary_fields;
|
} = job.summary_fields;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -114,20 +113,49 @@ function JobDetail ({ job, i18n }) {
|
|||||||
label={i18n._(t`Job Slice`)}
|
label={i18n._(t`Job Slice`)}
|
||||||
value={`${job.job_slice_number}/${job.job_slice_count}`}
|
value={`${job.job_slice_number}/${job.job_slice_count}`}
|
||||||
/>
|
/>
|
||||||
{(instanceGroups && instanceGroups.length > 0) && (
|
{(credentials && credentials.length > 0) && (
|
||||||
<Detail
|
<Detail
|
||||||
fullWidth
|
fullWidth
|
||||||
label={i18n._(t`Instance Groups`)}
|
label={i18n._(t`Credentials`)}
|
||||||
value={(
|
value={(
|
||||||
<ChipGroup showOverflowAfter={5}>
|
<ChipGroup showOverflowAfter={5}>
|
||||||
{instanceGroups.map(ig => (
|
{credentials.map(c => (
|
||||||
<Chip key={ig.id} isReadOnly>{ig.name}</Chip>
|
<Chip key={c.id} isReadOnly>{c.name}</Chip>
|
||||||
|
))}
|
||||||
|
</ChipGroup>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{(labels && labels.count > 0) && (
|
||||||
|
<Detail
|
||||||
|
fullWidth
|
||||||
|
label={i18n._(t`Credentials`)}
|
||||||
|
value={(
|
||||||
|
<ChipGroup showOverflowAfter={5}>
|
||||||
|
{labels.results.map(l => (
|
||||||
|
<Chip key={l.id} isReadOnly>{l.name}</Chip>
|
||||||
))}
|
))}
|
||||||
</ChipGroup>
|
</ChipGroup>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DetailList>
|
</DetailList>
|
||||||
|
<VariablesInput
|
||||||
|
css="margin: 20px 0"
|
||||||
|
id="job-variables"
|
||||||
|
readOnly
|
||||||
|
value={job.extra_vars}
|
||||||
|
rows={4}
|
||||||
|
label={i18n._(t`Variables`)}
|
||||||
|
/>
|
||||||
|
<VariablesInput
|
||||||
|
css="margin: 20px 0"
|
||||||
|
id="job-artifacts"
|
||||||
|
readOnly
|
||||||
|
value={job.artifacts ? JSON.stringify(job.artifacts) : '{}'}
|
||||||
|
rows={4}
|
||||||
|
label={i18n._(t`Artifacts`)}
|
||||||
|
/>
|
||||||
<ActionButtonWrapper>
|
<ActionButtonWrapper>
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
99
src/components/CodeMirrorInput/VariablesInput.jsx
Normal file
99
src/components/CodeMirrorInput/VariablesInput.jsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { string, func, bool, number } from 'prop-types';
|
||||||
|
import { Button, Split, SplitItem } from '@patternfly/react-core';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import ButtonGroup from '@components/ButtonGroup';
|
||||||
|
import { yamlToJson, jsonToYaml } from '@util/yaml';
|
||||||
|
import CodeMirrorInput from './CodeMirrorInput';
|
||||||
|
|
||||||
|
const YAML_MODE = 'yaml';
|
||||||
|
const JSON_MODE = 'javascript';
|
||||||
|
|
||||||
|
const SmallButton = styled(Button)`
|
||||||
|
padding: 3px 8px;
|
||||||
|
font-size: var(--pf-global--FontSize--xs);
|
||||||
|
`;
|
||||||
|
|
||||||
|
function VariablesInput (props) {
|
||||||
|
const { id, label, value, readOnly, rows, error, onChange, onError, className } = props;
|
||||||
|
const [mode, setMode] = useState(YAML_MODE);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`pf-c-form__group ${className || ''}`}>
|
||||||
|
<Split gutter="sm">
|
||||||
|
<SplitItem>
|
||||||
|
<label htmlFor={id} className="pf-c-form__label">{label}</label>
|
||||||
|
</SplitItem>
|
||||||
|
<SplitItem>
|
||||||
|
<ButtonGroup>
|
||||||
|
<SmallButton
|
||||||
|
onClick={() => {
|
||||||
|
if (mode === YAML_MODE) { return; }
|
||||||
|
try {
|
||||||
|
onChange(jsonToYaml(value));
|
||||||
|
setMode(YAML_MODE);
|
||||||
|
} catch (err) {
|
||||||
|
onError(err.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
variant={mode === YAML_MODE ? 'primary' : 'secondary'}
|
||||||
|
>
|
||||||
|
YAML
|
||||||
|
</SmallButton>
|
||||||
|
<SmallButton
|
||||||
|
onClick={() => {
|
||||||
|
if (mode === JSON_MODE) { return; }
|
||||||
|
try {
|
||||||
|
onChange(yamlToJson(value));
|
||||||
|
setMode(JSON_MODE);
|
||||||
|
} catch (err) {
|
||||||
|
onError(err.message);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
variant={mode === JSON_MODE ? 'primary' : 'secondary'}
|
||||||
|
>
|
||||||
|
JSON
|
||||||
|
</SmallButton>
|
||||||
|
</ButtonGroup>
|
||||||
|
</SplitItem>
|
||||||
|
</Split>
|
||||||
|
<CodeMirrorInput
|
||||||
|
mode={mode}
|
||||||
|
readOnly={readOnly}
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
rows={rows}
|
||||||
|
hasErrors={!!error}
|
||||||
|
/>
|
||||||
|
{error ? (
|
||||||
|
<div
|
||||||
|
className="pf-c-form__helper-text pf-m-error"
|
||||||
|
aria-live="polite"
|
||||||
|
>
|
||||||
|
{error}
|
||||||
|
</div>
|
||||||
|
) : null }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
VariablesInput.propTypes = {
|
||||||
|
id: string.isRequired,
|
||||||
|
label: string.isRequired,
|
||||||
|
value: string.isRequired,
|
||||||
|
readOnly: bool,
|
||||||
|
error: string,
|
||||||
|
rows: number,
|
||||||
|
onChange: func,
|
||||||
|
onError: func,
|
||||||
|
};
|
||||||
|
VariablesInput.defaultProps = {
|
||||||
|
readOnly: false,
|
||||||
|
onChange: () => {},
|
||||||
|
rows: 6,
|
||||||
|
error: null,
|
||||||
|
onError: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default styled(VariablesInput)`
|
||||||
|
--pf-c-form__label--FontSize: var(--pf-global--FontSize--sm);
|
||||||
|
`;
|
Loading…
Reference in New Issue
Block a user