Skip to content

Commit

Permalink
ADDON-34746: Intial commit for Edit/Clone/Delete Functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mamin-crest committed Mar 20, 2021
1 parent 0453cf3 commit d5bc04d
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class BaseFormView extends PureComponent{

static contextType=InputRowContext;

constructor(props) {
constructor(props,context) {
super(props);

// flag for to render hook method for once
Expand All @@ -38,6 +38,8 @@ class BaseFormView extends PureComponent{
utilCustomFunctions:this.util
};



if (props.isInput) {
globalConfig.pages.inputs.services.forEach((service) => {
if (service.name === props.serviceName) {
Expand All @@ -48,6 +50,11 @@ class BaseFormView extends PureComponent{
}
}
});

if(props.mode === MODE_EDIT || props.mode === MODE_CLONE){
this.currentInput = context.rowData[props.serviceName][props.stanzaName];
}

} else {
globalConfig.pages.tabs.forEach((tab) => {
if (tab.name === props.serviceName) {
Expand All @@ -72,17 +79,18 @@ class BaseFormView extends PureComponent{
temState[e.field] = tempEntity;
}
else if (props.mode === MODE_EDIT) {
tempEntity.value = (typeof props.currentInput[e.field] !== "undefined") ? props.currentInput[e.field] : null;
tempEntity.value = (typeof this.currentInput[e.field] !== "undefined") ? this.currentInput[e.field] : undefined;
tempEntity.display = (typeof e?.options?.display !== "undefined")?e.options.display:true;
tempEntity.error = false;
tempEntity.disabled = (typeof e?.options?.disableonEdit !== "undefined")?e.options.disableonEdit:false;
// eslint-disable-next-line no-nested-ternary
tempEntity.disabled = e.field === 'name' ? true : ( (typeof e?.options?.disableonEdit !== "undefined") ? e.options.disableonEdit : false);
temState[e.field] = tempEntity;
}
else if (props.mode === MODE_CLONE){
tempEntity.value = e.field === 'name' ? '' : props.currentInput[e.field];
tempEntity.value = e.field === 'name' ? '' : this.currentInput[e.field];
tempEntity.display = (typeof e?.options?.display !== "undefined") ? e.options.display:true;
tempEntity.error = false;
tempEntity.disabled =e.field==='name';
tempEntity.disabled =false;
temState[e.field] = tempEntity;
}
else{
Expand Down Expand Up @@ -177,13 +185,12 @@ class BaseFormView extends PureComponent{
this.hook.onSaveFail();
}
this.props.handleFormSubmit(false,false);
return Promise.reject(error);
return Promise.reject(err);
}).then((response) => {

const val = response?.data?.entry[0];
const tmpObj ={};


tmpObj[val.name] = {
...val.content,
id: val.id,
Expand All @@ -192,7 +199,6 @@ class BaseFormView extends PureComponent{
};

this.context.setRowData( update(this.context.rowData,{[this.props.serviceName]: {$merge : tmpObj}}))
console.log("Save Success : ",this.context.rowData);
this.props.handleFormSubmit(false,true);

});
Expand Down Expand Up @@ -335,12 +341,12 @@ class BaseFormView extends PureComponent{
return null;
}

generatesubmitMessage = () => {
if (this.state.isSubmitting) {
generateWarningMessage = () => {
if (this.state.WarningMsg) {
return (
<div>
<Message appearance="fill" type="error">
{this.state.ErrorMsg}
<Message appearance="fill" type="warning">
{this.state.WarningMsg}
</Message>
</div>
)
Expand Down Expand Up @@ -384,7 +390,7 @@ class BaseFormView extends PureComponent{

return(
<div className="form-horizontal">
{this.generatesubmitMessage()}
{this.generateWarningMessage()}
{this.generateErrorMessage()}
{
this.entities.map( (e) => {
Expand All @@ -400,7 +406,7 @@ class BaseFormView extends PureComponent{
entity={e}
serviceName={this.props.serviceName}
mode={this.props.mode}
disabled={temState.disbled}
disabled={temState.disabled}
dependencyValues={temState.dependencyValues || null}
/>)

Expand All @@ -414,8 +420,8 @@ class BaseFormView extends PureComponent{
BaseFormView.propTypes = {
isInput: PropTypes.bool,
serviceName: PropTypes.string,
stanzaName: PropTypes.string,
mode: PropTypes.string,
currentInput: PropTypes.object,
handleFormSubmit: PropTypes.func
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ControlWrapper extends React.PureComponent {
render(){

const { field, options, type, label, tooltip, help, encrypted = false } = this.props.entity;

const {handleChange, addCustomValidator, utilCustomFunctions} = this.props.utilityFuncts;
let rowView;
if(this.props.entity.type==="custom"){

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Button from '@splunk/react-ui/Button';
import Modal from '@splunk/react-ui/Modal';
import Message from '@splunk/react-ui/Message';
import styled from 'styled-components';
import WaitSpinner from '@splunk/react-ui/WaitSpinner';
import update from 'immutability-helper';

import { axiosCallWrapper } from '../util/axiosCallWrapper';
import InputRowContext from '../context/InputRowContext';

const ModalWrapper = styled(Modal)`
width: 800px
`;

class DeleteModal extends Component {
static contextType=InputRowContext;

constructor(props){
super(props);
this.state = {isDeleting:false,ErrorMsg:""};
}

handleRequestClose = () => {
this.props.handleRequestClose();
};

parseErrorMsg = (msg) => {
let errorMsg = ''; let regex; let matches;
try {
regex = /.+"REST Error \[[\d]+\]:\s+.+\s+--\s+([\s\S]*)"\.\s*See splunkd\.log(\/python.log)? for more details\./;
matches = regex.exec(msg);
if (matches && matches[1]) {
try {
const innerMsgJSON = JSON.parse(matches[1]);
errorMsg = String(innerMsgJSON.messages[0].text);
} catch (error) {
// eslint-disable-next-line prefer-destructuring
errorMsg = matches[1];
}
} else {
errorMsg = msg;
}
} catch (err) {
errorMsg = 'Error in processing the request';
}
return errorMsg;
}

handleDelete = () => {
this.setState( (prevState)=> {
return {...prevState, isDeleting:true,ErrorMsg:""}
}, ()=>{

axiosCallWrapper({
serviceName: `${this.props.serviceName}/${this.props.stanzaName}`,
customHeaders: { 'Content-Type': 'application/x-www-form-urlencoded' },
method: 'delete',
handleError: false
}).catch((err) => {
const errorSubmitMsg= this.parseErrorMsg(err?.response?.data?.messages[0]?.text);
this.setState({ErrorMsg:errorSubmitMsg,isDeleting:false});
return Promise.reject(err);

}).then((response) => {

this.context.setRowData( update(this.context.rowData,{[this.props.serviceName]: {$unset : [this.props.stanzaName]}}))
this.setState({isDeleting:false});
this.handleRequestClose()

});
});


};

// Display error message
generateErrorMessage = () => {
if (this.state.ErrorMsg) {
return (
<div>
<Message appearance="fill" type="error">
{this.state.ErrorMsg}
</Message>
</div>
)
}
return null;
}

render() {
let deleteMsg;
if(this.props.isInput){
deleteMsg = `Are you sure you want to delete "${this.props.stanzaName}" ?`;
}
else{
deleteMsg = `Are you sure you want to delete "${this.props.stanzaName}" ? Ensure that no input is configured with "${this.props.stanzaName}" as this will stop data collection for that input.`;
}
return (
<div>
<ModalWrapper onRequestClose={this.handleRequestClose} open={this.props.open}>
<Modal.Header
title="Delete Confirmation"
onRequestClose={this.handleRequestClose}
/>
<Modal.Body>
{this.generateErrorMessage()}
<p>{ deleteMsg }</p>
</Modal.Body>
<Modal.Footer>
<Button
appearance="secondary"
onClick={this.handleRequestClose}
label="Cancel"
/>
<Button appearance="primary"
label={this.state.isDeleting?<WaitSpinner/>:"Delete"}
onClick={this.handleDelete}
disabled={this.state.isDeleting}
/>
</Modal.Footer>
</ModalWrapper>
</div>
);
}
}

DeleteModal.propTypes = {
isInput: PropTypes.bool,
open: PropTypes.bool,
handleRequestClose: PropTypes.func,
serviceName: PropTypes.string,
stanzaName: PropTypes.string
};

export default DeleteModal;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Modal from '@splunk/react-ui/Modal';
import styled from 'styled-components';
import WaitSpinner from '@splunk/react-ui/WaitSpinner';

import { MODE_CLONE, MODE_CREATE, MODE_EDIT } from '../constants/modes';
import BaseFormView from './BaseFormView';

const ModalWrapper = styled(Modal)`
Expand All @@ -16,6 +17,19 @@ class EntityModal extends Component {
super(props);
this.form = React.createRef();
this.state = {isSubmititng:false};

if(props.mode === MODE_CREATE){
this.buttonText ="Add";
}
else if(props.mode === MODE_CLONE){
this.buttonText = "Save";
}
else if(props.mode ===MODE_EDIT){
this.buttonText = "Update";
}
else{
this.buttonText = "Submit";
}
}

handleRequestClose = () => {
Expand Down Expand Up @@ -50,7 +64,7 @@ class EntityModal extends Component {
isInput={this.props.isInput}
serviceName={this.props.serviceName}
mode={this.props.mode}
currentInput={this.props.currentInput}
stanzaName={this.props.stanzaName}
handleFormSubmit={this.handleFormSubmit}
/>
</Modal.Body>
Expand All @@ -61,7 +75,7 @@ class EntityModal extends Component {
label="Cancel"
/>
<Button appearance="primary"
label={this.state.isSubmititng?<WaitSpinner/>:"Submit"}
label={this.state.isSubmititng?<WaitSpinner/>:this.buttonText}
onClick={this.handleSubmit}
disabled={this.state.isSubmititng}
/>
Expand All @@ -78,7 +92,7 @@ EntityModal.propTypes = {
handleRequestClose: PropTypes.func,
serviceName: PropTypes.string,
mode: PropTypes.string,
currentInput: PropTypes.object,
stanzaName: PropTypes.string,
formLabel: PropTypes.string
};

Expand Down

0 comments on commit d5bc04d

Please sign in to comment.