Skip to content

Commit

Permalink
Convert EditWidgetModal
Browse files Browse the repository at this point in the history
  • Loading branch information
mshriver committed Feb 4, 2025
1 parent acbc040 commit 676ed9a
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 146 deletions.
276 changes: 132 additions & 144 deletions frontend/src/components/edit-widget-modal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';

import {
Expand All @@ -20,168 +20,156 @@ import { Settings } from '../settings';
import { linkifyDecorator } from './decorators';


const EditWidgetModal = (props) => {
const {
onSave,
onClose,
isOpen,
data,
} = props;

export class EditWidgetModal extends React.Component {
static propTypes = {
onSave: PropTypes.func,
onClose: PropTypes.func,
isOpen: PropTypes.bool,
data: PropTypes.object,
};

constructor(props) {
super(props);
this.state = {
widgetType: null,
title: props.data.title,
params: props.data.params,
weight: props.data.weight,
isTitleValid: true,
areParamsFilled: true,
componentLoaded: false,
};
}
const [widgetType, setWidgetType] = useState(null);
const [title, setTitle] = useState();
const [weight, setWeight] = useState();

// TODO: move the widget params to their own component to better handle validation?
const [componentLoaded, setComponentLoaded] = useState(false);
const [params, setParams] = useState();

onNameChange = (name) => {
this.setState({name});
}
const [isTitleValid, setIsTitleValid] = useState(title !== '');
const [saveButtonDisabled, setSaveButtonDisabled] = useState(false);

onExpiryDateChange = (expiryStr) => {
this.setState({expiryDate: expiryStr});
}

onSave = () => {
const onSaveModal = () => {
const updatedWidget = {
title: this.state.title,
params: this.state.params,
weight: parseInt(this.state.weight),
title: title,
params: params,
weight: parseInt(weight) || 0, // 400 if this is null
type: 'widget',
widget: this.props.data.widget
widget: data.widget
}
this.props.onSave(updatedWidget);
this.setState({
widgetType: null,
title: '',
params: {},
weight: 0,
isTitleValid: false,
areParamsFilled: false
});
}

onClose = () => {
this.setState({
title: '',
params: {},
weight: 0,
isTitleValid: false,
areParamsFilled: false,
});
this.props.onClose();
}
onSave(updatedWidget);

onTitleChange = (value) => {
this.setState({title: value, isTitleValid: (value !== '')});
setTitle('');
setParams({});
setWeight(0);
setIsTitleValid(false);
setWidgetType();
}

onWeightChange = (value) => {
this.setState({weight: value});
const onCloseModal = () => {
setTitle('');
setParams({});
setWeight(0);
setIsTitleValid(false);
onClose();
}

onParamChange = (value, event) => {
const params = this.state.params;
let areParamsFilled = true;
if (event) {
params[event.target.name] = value;
}
this.setState({params: params});
this.state.widgetType.params.forEach(widgetParam => {
if ((widgetParam.required) && (!params[widgetParam.name])) {
areParamsFilled = false;
}
});
this.setState({areParamsFilled: areParamsFilled});
useEffect(() => {
setTitle(data.title);
setWeight(data ? data.weight : 0);
setParams(data.params);
}, [data])

useEffect(() => {
let validCheck = (title !== '')
setIsTitleValid(validCheck);
if (validCheck) {setSaveButtonDisabled(false)}
else {setSaveButtonDisabled(true)}
}, [title])

const onParamChange = (value, event) => {
setParams(
...params,
params[event.target.name] = (event) ? value : params[event.target.name]
);
}

componentDidMount() {
useEffect(() =>{
HttpClient.get([Settings.serverUrl, 'widget', 'types'], {'type': 'widget'})
.then(response => HttpClient.handleResponse(response))
.then(data => {
data.types.forEach(type => {
if (type.id == this.props.data.widget) {
this.setState({widgetType: type});
this.setState({componentLoaded: true});
}
});
.then(response => HttpClient.handleResponse(response))
.then(data => {
data.types.forEach(type => {
if (type.id == data.widget) {
setWidgetType(type);
setComponentLoaded(true);
}
});
}

render () {
const { widgetType, componentLoaded } = this.state;
return (
<Modal
variant={ModalVariant.small}
title="Edit widget"
isOpen={this.props.isOpen}
onClose={this.onClose}
actions={[
<Button key="save" variant="primary" onClick={this.onSave}>Save</Button>,
<Button key="cancel" variant="link" onClick={this.onClose}>Cancel</Button>
]}
>
<Form>
<FormGroup label="Title" fieldId="widget-title" validated={this.isTitleValid} isRequired>
<TextInput type="text" id="widget-title" name="widget-title" value={this.state.title} onChange={(_event, value) => this.onTitleChange(value)} validated={this.state.isTitleValid} isRequired />
{this.state.isTitleValid !== true && (
<FormHelperText>
<HelperText>
<HelperTextItem icon={<ExclamationCircleIcon />} variant="error">
Please enter a title for this widget
</HelperTextItem>
</HelperText>
</FormHelperText>
)}
</FormGroup>
<FormGroup label="Weight" fieldId="widget-weight">
<TextInput type="number" id="widget-weight" name="widget-weight" value={this.state.weight} onChange={(_event, value) => this.onWeightChange(value)} />
});
}, [])

return (
<Modal
variant={ModalVariant.small}
title="Edit widget"
isOpen={isOpen}
onClose={onCloseModal}
actions={[
<Button key="save" variant="primary" onClick={onSaveModal} isDisabled={saveButtonDisabled}>Save</Button>,
<Button key="cancel" variant="link" onClick={onCloseModal}>Cancel</Button>
]}
>
<Form>
<FormGroup label="Title" fieldId="widget-title" validated={isTitleValid.toString()} isRequired>
<TextInput type="text" id="widget-title" name="widget-title" value={title} onChange={(_event, value) => setTitle(value)} validated={isTitleValid.toString()} isRequired />
{isTitleValid !== true && (
<FormHelperText>
<HelperText>
<HelperTextItem variant="default">
How widgets are ordered on the dashboard
<HelperTextItem icon={<ExclamationCircleIcon />} variant="error">
Please enter a title for this widget
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
{componentLoaded ? widgetType.params.map(param => (
<React.Fragment key={param.name}>
<FormGroup
label={param.name}
fieldId={param.name}
isRequired={param.required}>
<TextInput
value={this.state.params[param.name]}
type={(param.type === 'integer' || param.type === 'float') ? 'number' : 'text'}
id={param.name}
aria-describedby={`${param.name}-helper`}
name={param.name}
onChange={(event, value) => this.onParamChange(value, event)}
isRequired={param.required}
/>
<FormHelperText>
<HelperText>
<HelperTextItem variant="default">
<Linkify componentDecorator={linkifyDecorator}>
{param.description}
</Linkify>
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
</React.Fragment>
)): ''}
</Form>
</Modal>
);
}
)}
</FormGroup>
<FormGroup label="Weight" fieldId="widget-weight">
<TextInput type="number" id="widget-weight" name="widget-weight" value={weight} onChange={(_event, value) => setWeight(value)} />
<FormHelperText>
<HelperText>
<HelperTextItem variant="default">
How widgets are ordered on the dashboard
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
{componentLoaded ? widgetType.params.map(param => (
<React.Fragment key={param.name}>
<FormGroup
label={param.name}
fieldId={param.name}
isRequired={param.required}
validated={(params[param.name] !== '').toString()}>
<TextInput
value={params[param.name]}
type={(param.type === 'integer' || param.type === 'float') ? 'number' : 'text'}
id={param.name}
aria-describedby={`${param.name}-helper`}
name={param.name}
onChange={(event, value) => onParamChange(value, event)}
isRequired={param.required}
/>
<FormHelperText>
<HelperText>
<HelperTextItem variant="default">
<Linkify componentDecorator={linkifyDecorator}>
{param.description}
</Linkify>
</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
</React.Fragment>
)): ''}
</Form>
</Modal>
);

}

EditWidgetModal.propTypes = {
onSave: PropTypes.func,
onClose: PropTypes.func,
isOpen: PropTypes.bool,
data: PropTypes.object,
}

export default EditWidgetModal;
1 change: 0 additions & 1 deletion frontend/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ export { TabTitle } from './tabs';
export { TableEmptyState, TableErrorState } from './tablestates';
export { UserDropdown } from './user-dropdown';
export { View } from './view';
export { EditWidgetModal } from './edit-widget-modal';
3 changes: 2 additions & 1 deletion frontend/src/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle
import { HttpClient } from './services/http';
import { KNOWN_WIDGETS } from './constants';
import { Settings } from './settings';
import { NewDashboardModal, NewWidgetWizard, EditWidgetModal } from './components';
import { NewDashboardModal, NewWidgetWizard } from './components';
import EditWidgetModal from './components/edit-widget-modal.js'
import DeleteModal from './components/delete-modal.js';
import {
GenericAreaWidget,
Expand Down

0 comments on commit 676ed9a

Please sign in to comment.