import React from 'react' import Modal from 'react-modal' import Dialog from 'react-dialog' import LeafField from './editor/LeafField' import yang from '../yang/leaf-utils.js' import changeCase from 'change-case' const Button = ({ name, onClick, disabled }) => ( ); const ButtonBar = ({ submitName, submitDisabled, onSubmit, onCancel }) => (
); function initErrorInfo(leaves, container) { return leaves.reduce((errorInfo, p) => { const value = container && container[p.name]; const readOnly = p.isKey && !operation.isCreate; if (!readOnly && p.mandatory && !value) { errorInfo[p.name] = 'required'; } return errorInfo; }, {}) } function buildChoiceProperty(choiceProperty) { let description = choiceProperty.description + ' '; const choices = choiceProperty.properties.reduce((o, p) => { o[p.name] = { value: p.name }; description = `${description} ${p.name} - ${p.description}`; return o; }, {}); const choicePicker = Object.assign({}, choiceProperty); choicePicker['type'] = 'leaf'; choicePicker['description'] = description; choicePicker['data-type'] = { enumeration: { enum: choices } } return choicePicker; } function getIntialState(props) { const { isOpen, model, path, operation } = props; const baseLeaves = []; const choices = []; const dataSet = {}; const errorInfo = {}; let shadowErrorInfo = {}; let leaves = baseLeaves; if (isOpen && path && !operation.isDelete) { const element = model.getElement(path); const dataDivided = { leaf: baseLeaves, leaf_list: baseLeaves, choice: choices, }; element.schema.properties.forEach((property, index) => { const list = dataDivided[property.type] list && list.push(property) }); if (!operation.isCreate) { // we are not going to prompt for choices so add in appropriate files now choices.forEach((choice) => { const caseSelected = choice.properties.find(c => c.properties && c.properties.some(p => element.value[p.name])); if (caseSelected) { caseSelected.properties.forEach(p => yang.isLeafOrLeafList(p) && baseLeaves.push(p)); } }); } else { // on create we first propmt for "features" leaves = choices.map(choice => buildChoiceProperty(choice)); } shadowErrorInfo = initErrorInfo(leaves, element.value); } return { dataSet, shadowErrorInfo, errorInfo, baseLeaves, leaves, choices }; } export default class extends React.Component { constructor(props) { super(props); this.state = getIntialState(props); this.state.showHelp = true; } handleCloseEditor = () => { }; componentWillReceiveProps(nextProps) { if (this.props.isOpen !== nextProps.isOpen) { this.setState(getIntialState(nextProps)); } } render() { try { const { isOpen, model, isReadonly, properties, operation, onSave, onCancel } = this.props; if (!isOpen) { return null; } let dataPath = this.props.path.slice(); const element = model.getElement(dataPath); const container = element.value; let editors = null; let submitHandler = () => { if (Object.keys(this.state.errorInfo).length === 0) { onSave(this.state.dataSet); } } const checkForSubmitKey = (e) => { if (e.keyCode == 13) { e.preventDefault(); e.stopPropagation(); submitHandler(); } }; let submitButtonLabel = operation.isCreate ? "Add" : "Save"; let submitDisabled = true; let headerText = null; if (operation.isDelete) { const id = dataPath[dataPath.length - 1]; const deletePrompt = `Delete ${id}?`; submitButtonLabel = "Delete"; submitDisabled = false; editors = (
{deletePrompt}
); } else { let { leaves, choices } = this.state; if (choices.length) { if (operation.isCreate) { headerText = `Select feature(s) for ${element.name}` submitButtonLabel = "Continue"; submitHandler = () => { const { dataSet, baseLeaves } = this.state; const leaves = choices.reduce((leafList, choice) => { const caseSelected = dataSet[choice.name].value; delete dataSet[choice.name]; if (caseSelected) { return leafList.concat(choice.properties.find((p) => p.name === caseSelected).properties.reduce((list, p) => { yang.isLeafOrLeafList(p) && list.push(p); return list; }, [])); } return leafList; }, baseLeaves.slice()); const shadowErrorInfo = initErrorInfo(leaves, element.value); this.setState({ dataSet, leaves, choices: [], errorInfo: {}, shadowErrorInfo }); } } } submitDisabled = (Object.keys(this.state.shadowErrorInfo).length || (!operation.isCreate && Object.keys(this.state.dataSet).length === 0)); // process the named field value change function processFieldValueChange(property, currentValue, value) { console.debug(`processed change for -- ${name} -- with value -- ${value}`); const dataSet = this.state.dataSet; const name = property.name; if ((currentValue && currentValue !== value) || (!currentValue && value)) { dataSet[name] = { property, value, currentValue }; } else { delete dataSet[name]; } const { errorInfo, shadowErrorInfo } = this.state; delete errorInfo[name]; delete shadowErrorInfo[name]; this.setState({ dataSet, errorInfo, shadowErrorInfo }); } function onErrorHandler(name, message) { const { errorInfo, shadowErrorInfo } = this.state; errorInfo[name] = message; shadowErrorInfo[name] = message; this.setState({ errorInfo, shadowErrorInfo }); } editors = leaves.reduce((editors, property, index) => { const itemPath = dataPath.slice(); itemPath.push(property.name); const props = { model, 'path': itemPath }; const value = container && container[property.name]; let readOnly = isReadonly; let extraHelp = null; if (!isReadonly) { if (yang.isKey(property) && !operation.isCreate) { extraHelp = "Id fields are not modifiable."; readOnly = true; } else if (yang.isLeafList(property)) { extraHelp = "Enter a comma separated list of values." } } editors.push( ); return editors; }, []) } const customStyles = { content: { top: '50%', left: '50%', right: 'auto', bottom: 'auto', marginRight: '-50%', transform: 'translate(-50%, -50%)' } }; const dlgHeader = headerText ? (
{headerText}
) : null; return (
{dlgHeader} {editors}
) } catch (e) { console.error("component render", e); } } }