Skip to content

Commit

Permalink
Updated design of user settings
Browse files Browse the repository at this point in the history
  • Loading branch information
bond95 committed Oct 23, 2019
1 parent 224f82f commit 247505a
Show file tree
Hide file tree
Showing 39 changed files with 721 additions and 1,131 deletions.
51 changes: 5 additions & 46 deletions src/actions/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import {
GET_SSH_KEY,
SAVE_OPTION,
SAVE_GLOBAL_OPTIONS,
SAVE_OPTION_TO_VMS,
SAVE_SSH_KEY,
SAVE_VM_OPTIONS,
SAVE_VMS_OPTIONS,
SET_SSH_KEY,
SET_OPTION,
SET_OPTION_TO_VMS,
SET_OPTIONS_SAVE_RESULTS,
RESET_GLOBAL_SETTINGS,
RESET_OPTIONS,
RESET_VM_SETTINGS,
} from '_/constants'

export function getSSHKey ({ userId }) {
Expand Down Expand Up @@ -67,25 +63,24 @@ export function saveOption ({ key, value, vmId }) {
}
}

export function saveGlobalOptions ({ values, checkedVms }, { correlationId }) {
export function saveGlobalOptions ({ values }, { correlationId }) {
return {
type: SAVE_GLOBAL_OPTIONS,
payload: {
values,
checkedVms,
},
meta: {
correlationId,
},
}
}

export function saveVmOptions ({ values, vmId }, { correlationId }) {
export function saveVmsOptions ({ values, vmIds }, { correlationId }) {
return {
type: SAVE_VM_OPTIONS,
type: SAVE_VMS_OPTIONS,
payload: {
values,
vmId,
vmIds,
},
meta: {
correlationId,
Expand All @@ -104,42 +99,6 @@ export function setOptionsSaveResults ({ correlationId, status, details }) {
}
}

export function saveOptionToVms ({ key, value, vmIds, values }) {
return {
type: SAVE_OPTION_TO_VMS,
payload: {
key,
value,
vmIds,
values,
},
}
}

export function resetGlobalSettings () {
return {
type: RESET_GLOBAL_SETTINGS,
}
}

export function resetVmSettings ({ vmId }) {
return {
type: RESET_VM_SETTINGS,
payload: {
vmId,
},
}
}

export function resetOptions ({ vmId } = {}) {
return {
type: RESET_OPTIONS,
payload: {
vmId,
},
}
}

export function saveSSHKey ({ key, userId, sshId }) {
return {
type: SAVE_SSH_KEY,
Expand Down
19 changes: 10 additions & 9 deletions src/components/Pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,36 @@ class VmSettingsPage extends React.Component {
constructor (props) {
super(props)
this.state = {
vmId: undefined,
vmIds: [],
}
}

static getDerivedStateFromProps (props, state) {
if (state.vmId !== props.match.params.id) {
const vmId = props.match.params.id
return { vmId }
const ids = props.match.params.id.split('/')
if (ids.filter(n => !state.vmIds.includes(n)).length > 0) {
return { vmIds: ids }
}

return null
}

render () {
const { vms } = this.props
const { vmId } = this.state
const { vms, route } = this.props
const { vmIds } = this.state

if (vmId && vms.getIn(['vms', vmId])) {
return (<VmSettings vm={vms.getIn(['vms', vmId])} />)
if (vmIds.length > 0 && vmIds.filter(n => !vms.get('vms').keySeq().includes(n)).length === 0) {
return (<VmSettings selectedVms={vmIds} {...route.pageProps} />)
}

// TODO: Add handling for if the fetch runs but fails (FETCH-FAIL), see issue #631
console.info(`VmSettingsPage: VM id cannot be found: ${vmId}`)
console.info(`VmSettingsPage: VM id cannot be found: ${vmIds}`)
return null
}
}

VmSettingsPage.propTypes = {
vms: PropTypes.object.isRequired,
route: PropTypes.object.isRequired,
match: RouterPropTypeShapes.match.isRequired,
}
const VmSettingsPageConnected = connect(
Expand Down
File renamed without changes.
83 changes: 83 additions & 0 deletions src/components/Settings/SettingsBase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
Card,
Col,
ControlLabel,
FormGroup,
FieldLevelHelp,
} from 'patternfly-react'

import style from './style.css'

const LabelCol = ({ children, tooltip, ...props }) => {
return <Col componentClass={ControlLabel} {...props}>
{ children } { tooltip && <FieldLevelHelp disabled={false} content={tooltip} inline /> }
</Col>
}
LabelCol.propTypes = {
children: PropTypes.node.isRequired,
tooltip: PropTypes.string,
}

const Item = ({ title, isActive, onClick }) => {
return <li className={`list-group-item ${isActive && 'active'}`}>
<a href='#' onClick={(e) => { e.preventDefault(); onClick() }}>
<span className='list-group-item-value'>{title}</span>
<div className='badge-container-pf' />
</a>
</li>
}

Item.propTypes = {
title: PropTypes.string.isRequired,
isActive: PropTypes.bool,
onClick: PropTypes.func.isRequired,
}

const Section = ({ name, section }) => (
<React.Fragment>
<h3><a id={name} />{section.title} { section.tooltip && <FieldLevelHelp disabled={false} content={section.tooltip} inline /> }</h3>
{ section.fields.map((field) => (
<FormGroup key={field.title} className={style['settings-field']}>
<LabelCol tooltip={field.tooltip} sm={3} className={style['field-label']}>
{ field.title }
</LabelCol>
<Col sm={9}>
{field.body}
</Col>
</FormGroup>
)) }
</React.Fragment>
)

Section.propTypes = {
name: PropTypes.string.isRequired,
section: PropTypes.object.isRequired,
}

class SettingsBase extends Component {
buildSection (key, section) {
return (
<Card key={key} className={style['main-content']}>
<div className={style['main-content-container']}>
<Section name={key} section={section} />
</div>
</Card>
)
}

render () {
const { sections } = this.props
return (
<div className={style['search-content-box']}>
{Object.entries(sections).filter(([key, section]) => !!section).map(([key, section]) => this.buildSection(key, section))}
</div>
)
}
}
SettingsBase.propTypes = {
sections: PropTypes.object.isRequired,
}

export default SettingsBase
64 changes: 64 additions & 0 deletions src/components/Settings/SettingsToolbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import { Toolbar } from 'patternfly-react'
import { msg } from '_/intl'

import style from './style.css'

class SettingsToolbar extends React.Component {
constructor (props) {
super(props)
this.el = document.createElement('div')
}

componentDidMount () {
const root = document.getElementById('settings-toolbar')
if (root) {
root.appendChild(this.el)
}
}

componentWillUnmount () {
const root = document.getElementById('settings-toolbar')
if (root) {
root.removeChild(this.el)
}
}
render () {
const { onSave, onCancel } = this.props
const body = <Toolbar className={style['toolbar']}>
<Toolbar.RightContent>
<button
onClick={e => {
e.preventDefault()
onCancel()
}}
className='btn btn-default'
>
{msg.cancel()}
</button>
<button
onClick={e => {
e.preventDefault()
onSave()
}}
className='btn btn-primary'
>
{msg.save()}
</button>
</Toolbar.RightContent>
</Toolbar>
return ReactDOM.createPortal(
body,
this.el
)
}
}

SettingsToolbar.propTypes = {
onSave: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
}

export default SettingsToolbar
Loading

0 comments on commit 247505a

Please sign in to comment.