Skip to content

Commit

Permalink
use VariablesDetail for displaying variables field in details views
Browse files Browse the repository at this point in the history
  • Loading branch information
keithjgrant committed Dec 18, 2019
1 parent cde3941 commit 2f7607a
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 107 deletions.
1 change: 1 addition & 0 deletions awx/ui_next/src/components/Card/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as TabbedCardHeader } from './TabbedCardHeader';
105 changes: 60 additions & 45 deletions awx/ui_next/src/components/CodeMirrorInput/VariablesDetail.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { string, number } from 'prop-types';
import { Split, SplitItem } from '@patternfly/react-core';
import { Split, SplitItem, TextListItemVariants } from '@patternfly/react-core';
import { DetailName, DetailValue } from '@components/DetailList';
import CodeMirrorInput from './CodeMirrorInput';
import YamlJsonToggle from './YamlJsonToggle';
import { yamlToJson, jsonToYaml, isJson } from '../../util/yaml';
Expand All @@ -10,54 +11,68 @@ const JSON_MODE = 'javascript';

function VariablesDetail({ value, label, rows }) {
const [mode, setMode] = useState(isJson(value) ? JSON_MODE : YAML_MODE);
const [val, setVal] = useState(value);
const [currentValue, setCurrentValue] = useState(value);
const [error, setError] = useState(null);

return (
<div css="margin: 20px 0">
<Split gutter="sm">
<SplitItem>
<div className="pf-c-form__label">
<span
className="pf-c-form__label-text"
css="font-weight: var(--pf-global--FontWeight--bold)"
>
{label}
</span>
</div>
</SplitItem>
<SplitItem>
<YamlJsonToggle
mode={mode}
onChange={newMode => {
try {
const newVal =
newMode === YAML_MODE ? jsonToYaml(val) : yamlToJson(val);
setVal(newVal);
setMode(newMode);
} catch (err) {
setError(err);
}
}}
/>
</SplitItem>
</Split>
<CodeMirrorInput
mode={mode}
value={val}
readOnly
rows={rows}
css="margin-top: 10px"
/>
{error && (
<div
css="color: var(--pf-global--danger-color--100);
<>
<DetailName
component={TextListItemVariants.dt}
fullWidth
css="grid-column: 1 / -1"
>
<Split gutter="sm">
<SplitItem>
<div className="pf-c-form__label">
<span
className="pf-c-form__label-text"
css="font-weight: var(--pf-global--FontWeight--bold)"
>
{label}
</span>
</div>
</SplitItem>
<SplitItem>
<YamlJsonToggle
mode={mode}
onChange={newMode => {
try {
const newVal =
newMode === YAML_MODE
? jsonToYaml(currentValue)
: yamlToJson(currentValue);
setCurrentValue(newVal);
setMode(newMode);
} catch (err) {
setError(err);
}
}}
/>
</SplitItem>
</Split>
</DetailName>
<DetailValue
component={TextListItemVariants.dd}
fullWidth
css="grid-column: 1 / -1; margin-top: -20px"
>
<CodeMirrorInput
mode={mode}
value={currentValue}
readOnly
rows={rows}
css="margin-top: 10px"
/>
{error && (
<div
css="color: var(--pf-global--danger-color--100);
font-size: var(--pf-global--FontSize--sm"
>
Error: {error.message}
</div>
)}
</div>
>
Error: {error.message}
</div>
)}
</DetailValue>
</>
);
}
VariablesDetail.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import YamlJsonToggle from './YamlJsonToggle';
import { yamlToJson, jsonToYaml } from '../../util/yaml';

const YAML_MODE = 'yaml';
const JSON_MODE = 'javascript';

function VariablesField({ id, name, label, readOnly }) {
// TODO: detect initial mode
Expand Down
58 changes: 15 additions & 43 deletions awx/ui_next/src/screens/Host/HostDetail/HostDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import styled from 'styled-components';
import { Host } from '@types';
import { formatDateString } from '@util/dates';
import { Button, CardBody } from '@patternfly/react-core';
import { DetailList, Detail } from '@components/DetailList';
import CodeMirrorInput from '@components/CodeMirrorInput';
import { DetailList, Detail, UserDateDetail } from '@components/DetailList';
import { VariablesDetail } from '@components/CodeMirrorInput';

const ActionButtonWrapper = styled.div`
display: flex;
Expand All @@ -21,30 +20,6 @@ const ActionButtonWrapper = styled.div`
function HostDetail({ host, i18n }) {
const { created, description, id, modified, name, summary_fields } = host;

let createdBy = '';
if (created) {
if (summary_fields.created_by && summary_fields.created_by.username) {
createdBy = i18n._(
t`${formatDateString(created)} by ${summary_fields.created_by.username}`
);
} else {
createdBy = formatDateString(created);
}
}

let modifiedBy = '';
if (modified) {
if (summary_fields.modified_by && summary_fields.modified_by.username) {
modifiedBy = i18n._(
t`${formatDateString(modified)} by ${
summary_fields.modified_by.username
}`
);
} else {
modifiedBy = formatDateString(modified);
}
}

return (
<CardBody>
<DetailList gutter="sm">
Expand All @@ -66,23 +41,20 @@ function HostDetail({ host, i18n }) {
}
/>
)}
{/* TODO: Link to user in users */}
<Detail label={i18n._(t`Created`)} value={createdBy} />
{/* TODO: Link to user in users */}
<Detail label={i18n._(t`Last Modified`)} value={modifiedBy} />
<Detail
fullWidth
<UserDateDetail
label={i18n._(t`Created`)}
date={created}
user={summary_fields.created_by}
/>
<UserDateDetail
label={i18n._(t`Last Modified`)}
date={modified}
user={summary_fields.modified_by}
/>
<VariablesDetail
label={i18n._(t`Variables`)}
value={
<CodeMirrorInput
mode="yaml"
readOnly
value={host.variables}
onChange={() => {}}
rows={6}
hasErrors={false}
/>
}
value={host.variables}
rows={6}
/>
</DetailList>
<ActionButtonWrapper>
Expand Down
15 changes: 7 additions & 8 deletions awx/ui_next/src/screens/Host/HostDetail/HostDetail.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('<HostDetail />', () => {
mountWithContexts(<HostDetail host={mockHost} />);
});

test('should render Details', async done => {
test('should render Details', async () => {
const wrapper = mountWithContexts(<HostDetail host={mockHost} />);
const testParams = [
{ label: 'Name', value: 'Foo' },
Expand All @@ -46,23 +46,22 @@ describe('<HostDetail />', () => {
expect(detail.find('dt').text()).toBe(label);
expect(detail.find('dd').text()).toBe(value);
}
done();
});

test('should show edit button for users with edit permission', async done => {
test('should show edit button for users with edit permission', async () => {
const wrapper = mountWithContexts(<HostDetail host={mockHost} />);
const editButton = await waitForElement(wrapper, 'HostDetail Button');
// VariablesDetail has two buttons
const editButton = wrapper.find('Button').at(2);
expect(editButton.text()).toEqual('Edit');
expect(editButton.prop('to')).toBe('/hosts/1/edit');
done();
});

test('should hide edit button for users without edit permission', async done => {
test('should hide edit button for users without edit permission', async () => {
const readOnlyHost = { ...mockHost };
readOnlyHost.summary_fields.user_capabilities.edit = false;
const wrapper = mountWithContexts(<HostDetail host={readOnlyHost} />);
await waitForElement(wrapper, 'HostDetail');
expect(wrapper.find('HostDetail Button').length).toBe(0);
done();
// VariablesDetail has two buttons
expect(wrapper.find('Button').length).toBe(2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,13 @@ function InventoryDetail({ inventory, i18n }) {
)
}
/>
</DetailList>
{inventory.variables && (
<VariablesDetail
id="job-artifacts"
label={i18n._(t`Variables`)}
value={inventory.variables}
rows={4}
/>
)}
<DetailList>
{inventory.variables && (
<VariablesDetail
label={i18n._(t`Variables`)}
value={inventory.variables}
rows={4}
/>
)}
<UserDateDetail
label={i18n._(t`Created`)}
date={inventory.created}
Expand Down

0 comments on commit 2f7607a

Please sign in to comment.