Skip to content

Commit

Permalink
[WIP] VM Details
Browse files Browse the repository at this point in the history
  • Loading branch information
rszwajko committed Dec 23, 2021
1 parent 943bccf commit 6c4d0c6
Show file tree
Hide file tree
Showing 31 changed files with 663 additions and 832 deletions.
4 changes: 2 additions & 2 deletions src/components/Grid/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
position: relative;
width: 100%;
min-height: 1px;
padding-right: 20px;
padding-left: 20px;
padding-right: 10px;
padding-left: 10px;

flex: 1 1 0; /* grow shrink basis */
max-width: 100%;
Expand Down
47 changes: 20 additions & 27 deletions src/components/VmDetails/BaseCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@ import {
Badge,
Button,
Card,
CardHeading,
CardHeader,
CardTitle,
CardBody,
CardFooter,
Icon,
noop,
excludeKeys,
} from 'patternfly-react'
} from '@patternfly/react-core'

import style from './style.css'
import CardEditButton from './CardEditButton'
import { Tooltip } from '_/components/tooltips'
import { CheckIcon, TimesIcon } from '@patternfly/react-icons/dist/esm/icons'

/**
* Base VM details card. Support common layouts and view vs edit modes.
Expand Down Expand Up @@ -76,7 +74,7 @@ class BaseCard extends React.Component {
}

renderChildren (childProps) {
const children = this.props.children || noop
const children = this.props.children || (() => {})
return typeof children === 'function'
? children(childProps)
: React.isValidElement(children)
Expand All @@ -87,7 +85,7 @@ class BaseCard extends React.Component {
render () {
const {
title = undefined,
icon = undefined,
icon: TheIcon = undefined,
itemCount = undefined,
editMode = undefined,
editable = true,
Expand All @@ -101,13 +99,18 @@ class BaseCard extends React.Component {
const editing = editMode === undefined ? this.state.edit : editMode
const hasHeading = !!title
const hasBadge = itemCount !== undefined
const hasIcon = icon && icon.type && icon.name

const RenderChildren = this.renderChildren
return (
<Card className={`${style['base-card']} ${className}`} id={`${idPrefix}-card`} {...excludeKeys(this.props, this.propTypeKeys)}>
<Card className={`${style['base-card']} ${className}`} id={`${idPrefix}-card` } isCompact>
{hasHeading && (
<CardHeading className={style['base-card-heading']}>
<CardHeader className={style['base-card-heading']}>

<CardTitle>
{TheIcon && <TheIcon className={style['base-card-title-icon']} />}
{title}
{hasBadge && <Badge isRead>{itemCount}</Badge>}
</CardTitle>
<CardEditButton
tooltip={editTooltip}
editable={editable}
Expand All @@ -117,12 +120,7 @@ class BaseCard extends React.Component {
id={`${idPrefix}-button-edit`}
placement={editTooltipPlacement}
/>
<CardTitle>
{hasIcon && <Icon type={icon.type} name={icon.name} className={style['base-card-title-icon']} />}
{title}
{hasBadge && <Badge className={style['base-card-item-count-badge']}>{itemCount}</Badge>}
</CardTitle>
</CardHeading>
</CardHeader>
)}

<CardBody className={style['base-card-body']}>
Expand All @@ -143,10 +141,8 @@ class BaseCard extends React.Component {

{editing && (
<CardFooter className={style['base-card-footer']}>
<Button disabled={disableSaveButton} bsStyle='primary' onClick={this.clickSave} id={`${idPrefix}-button-save`}>
<Icon type='fa' name='check' />
</Button>
<Button onClick={this.clickCancel} id={`${idPrefix}-button-cancel`}><Icon type='pf' name='close' /></Button>
<Button isDisabled={disableSaveButton} onClick={this.clickSave} id={`${idPrefix}-button-save`} icon={<CheckIcon />}/>
<Button onClick={this.clickCancel} id={`${idPrefix}-button-cancel`} icon={<TimesIcon />} variant='link'/>
</CardFooter>
)}
</Card>
Expand All @@ -155,10 +151,7 @@ class BaseCard extends React.Component {
}
BaseCard.propTypes = {
title: PropTypes.string,
icon: PropTypes.shape({
type: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}),
icon: PropTypes.any,
itemCount: PropTypes.number,
idPrefix: PropTypes.string,
className: PropTypes.string,
Expand All @@ -176,9 +169,9 @@ BaseCard.propTypes = {
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,
}
BaseCard.defaultProps = {
onStartEdit: noop,
onCancel: noop,
onSave: noop,
onStartEdit: () => {},
onCancel: () => {},
onSave: () => {},
}

export default BaseCard
14 changes: 6 additions & 8 deletions src/components/VmDetails/CardEditButton.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import {
Icon,
noop,
} from 'patternfly-react'

import { PencilAltIcon } from '@patternfly/react-icons/dist/esm/icons'

import style from './style.css'

Expand Down Expand Up @@ -42,7 +40,7 @@ class CardEditButton extends React.Component {
const { editEnabled } = this.state

const classes = `${style['card-edit-button']} ${style[editEnabled ? 'card-edit-button-enabled' : 'card-edit-button-disabled']}`
const myClick = editEnabled ? noop : this.enableEditHandler
const myClick = editEnabled ? () => {} : this.enableEditHandler

if (!editable && disableTooltip) {
return (
Expand All @@ -52,7 +50,7 @@ class CardEditButton extends React.Component {
id={`${id}-card-edit-button-tooltip`}
>
<a className={`${style['card-edit-button']} ${style['card-edit-button-disabled']}`} id={id}>
<Icon type='pf' name='edit' />
<PencilAltIcon/>
</a>
</Tooltip>
)
Expand All @@ -64,7 +62,7 @@ class CardEditButton extends React.Component {
return (
<Tooltip id={`${id}-tooltip`} tooltip={tooltip} placement={placement}>
<a id={id} className={classes} onClick={(e) => { e.preventDefault(); myClick() }}>
<Icon type='pf' name='edit' />
<PencilAltIcon/>
</a>
</Tooltip>
)
Expand All @@ -82,7 +80,7 @@ CardEditButton.propTypes = {
CardEditButton.defaultProps = {
tooltip: '',
editEnabled: false,
onClick: noop,
onClick: () => {},
}

export default CardEditButton
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useContext } from 'react'
import PropTypes from 'prop-types'
import {
FormControl,
ControlLabel,
FormGroup,
} from 'patternfly-react'
TextArea,
TextInput,
} from '@patternfly/react-core'
import { MsgContext } from '_/intl'

const CloudInitForm = ({ idPrefix, vm, onChange }) => {
Expand All @@ -13,24 +13,25 @@ const CloudInitForm = ({ idPrefix, vm, onChange }) => {
const cloudInitSshAuthorizedKeys = vm.getIn(['cloudInit', 'sshAuthorizedKeys'])
return (
<>
<FormGroup controlId={`${idPrefix}-cloud-init-hostname`}>
<ControlLabel>
{msg.hostName()}
</ControlLabel>
<FormControl
type='text'
<FormGroup
label={msg.hostName()}
fieldId={`${idPrefix}-cloud-init-hostname`}
>
<TextInput
id={`${idPrefix}-cloud-init-hostname`}
type="text"
value={cloudInitHostName}
onChange={e => onChange('cloudInitHostName', e.target.value)}
onChange={value => onChange('cloudInitHostName', value)}
/>
</FormGroup>
<FormGroup controlId={`${idPrefix}-cloud-init-ssh`}>
<ControlLabel>
{msg.sshAuthorizedKeys()}
</ControlLabel>
<FormControl
componentClass='textarea'
<FormGroup
label={msg.sshAuthorizedKeys()}
fieldId={`${idPrefix}-cloud-init-ssh`}
>
<TextArea
id={`${idPrefix}-cloud-init-ssh`}
value={cloudInitSshAuthorizedKeys}
onChange={e => onChange('cloudInitSshAuthorizedKeys', e.target.value)}
onChange={value => onChange('cloudInitSshAuthorizedKeys', value)}
/>
</FormGroup>
</>
Expand Down
63 changes: 32 additions & 31 deletions src/components/VmDetails/cards/DetailsCard/CloudInit/SysprepForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React, { useContext } from 'react'
import PropTypes from 'prop-types'
import {
Checkbox,
ControlLabel,
FormControl,
FormGroup,
} from 'patternfly-react'
TextArea,
TextInput,
} from '@patternfly/react-core'
import { MsgContext } from '_/intl'
import SelectBox from '../../../../SelectBox'
import timezones from '_/components/utils/timezones.json'
Expand All @@ -19,40 +19,41 @@ const SysprepForm = ({ idPrefix, vm, onChange, lastInitTimezone }) => {

return (
<>
<FormGroup controlId={`${idPrefix}-cloud-init-hostname`}>
<ControlLabel>
{msg.hostName()}
</ControlLabel>
<FormControl
<FormGroup
label={msg.hostName()}
fieldId={`${idPrefix}-sysprep-hostname`}
>
<TextInput
id={`${idPrefix}-sysprep-hostname`}
type='text'
value={cloudInitHostName}
onChange={e => onChange('cloudInitHostName', e.target.value)}
onChange={value => onChange('cloudInitHostName', value)}
/>
</FormGroup>
<FormGroup controlId={`${idPrefix}-cloud-init-hostname`}>
<ControlLabel>
{msg.password()}
</ControlLabel>
<FormControl
<FormGroup
label={msg.password()}
fieldId={`${idPrefix}-sysprep-password`}
>
<TextInput
id={`${idPrefix}-sysprep-password`}
type='password'
value={cloudInitPassword}
onChange={e => onChange('cloudInitPassword', e.target.value)}
onChange={value => onChange('cloudInitPassword', value)}
/>
</FormGroup>

{/* Configure Timezone checkbox */}
<Checkbox
id={`${idPrefix}-sysprep-timezone-config`}
checked={enableInitTimezone}
onChange={e => onChange('enableInitTimezone', e.target.checked)}
>
{msg.sysPrepTimezoneConfigure()}
</Checkbox>
label={msg.sysPrepTimezoneConfigure()}
isChecked={enableInitTimezone}
onChange={checked => onChange('enableInitTimezone', checked)}
/>

<FormGroup controlId={`${idPrefix}-cloud-init-timezone`}>
<ControlLabel>
{msg.timezone()}
</ControlLabel>
<FormGroup
label={msg.timezone()}
fieldId={`${idPrefix}-sysprep-timezone-select`}
>
<SelectBox
id={`${idPrefix}-sysprep-timezone-select`}
items={timezones}
Expand All @@ -61,14 +62,14 @@ const SysprepForm = ({ idPrefix, vm, onChange, lastInitTimezone }) => {
disabled={!enableInitTimezone}
/>
</FormGroup>
<FormGroup controlId={`${idPrefix}-sysprep-custom-script`}>
<ControlLabel>
{msg.customScript()}
</ControlLabel>
<FormControl
componentClass='textarea'
<FormGroup
label={msg.customScript()}
fieldId={`${idPrefix}-sysprep-custom-script`}
>
<TextArea
id={`${idPrefix}-sysprep-custom-script`}
value={cloudInitCustomScript}
onChange={e => onChange('cloudInitCustomScript', e.target.value)}
onChange={value => onChange('cloudInitCustomScript', value)}
/>
</FormGroup>
</>
Expand Down
21 changes: 11 additions & 10 deletions src/components/VmDetails/cards/DetailsCard/FieldRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ import PropTypes from 'prop-types'

import { Col } from '_/components/Grid'
import { InfoTooltip, Tooltip } from '_/components/tooltips'
import { FormGroup, ControlLabel } from 'patternfly-react'
import { FormGroup } from '@patternfly/react-core'
import classnames from 'classnames'

import style from './style.css'
import gridStyle from '_/components/Grid/style.css'

const FieldRow = ({ label, children, id, tooltip, tooltipPosition, validationState = null }) => (
<FormGroup
className={classnames(gridStyle['grid-row'], style['field-row'])}
validationState={validationState}
>
const FieldRow = ({ label, children, id, tooltip, tooltipPosition, validationState = 'default' }) => (
<div className={classnames(gridStyle['grid-row'], style['field-row'])}>
<Col cols={5} className={style['col-label']}>
<ControlLabel>{label}</ControlLabel>
{label}
{tooltip && (
<span className={style.tooltip}>
<InfoTooltip
Expand All @@ -26,16 +23,20 @@ const FieldRow = ({ label, children, id, tooltip, tooltipPosition, validationSta
</span>
)}
</Col>
<Col cols={7} className={style['col-data']} id={id}>{children}</Col>
</FormGroup>
<Col cols={7} className={style['col-data']} id={id}>
<FormGroup validated={validationState}>
{children}
</FormGroup>
</Col>
</div>
)
FieldRow.propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
tooltip: PropTypes.oneOfType([Tooltip.propTypes.tooltip]),
children: PropTypes.node.isRequired,
tooltipPosition: Tooltip.propTypes.placement,
validationState: FormGroup.propTypes.validationState,
validationState: PropTypes.oneOf(['success', 'warning', 'error', 'default']),
}

export default FieldRow
Loading

0 comments on commit 6c4d0c6

Please sign in to comment.