/* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ import React from 'react' import {RaisedButton, FlatButton} from 'material-ui' /** * Editor for a given plugin. By default, displays documentation in a left column panel, * and plugin parameters as form cards on the right. * May take additionalPanes to be appended to the form cards. */ const PluginEditor = React.createClass({ mixins:[AdminComponents.MessagesConsumerMixin], propTypes:{ rootNode:React.PropTypes.instanceOf(AjxpNode).isRequired, close:React.PropTypes.func, style:React.PropTypes.string, className:React.PropTypes.string, additionalPanes:React.PropTypes.shape({ top:React.PropTypes.array, bottom:React.PropTypes.array }), docAsAdditionalPane:React.PropTypes.bool, additionalDescription:React.PropTypes.string, registerCloseCallback:React.PropTypes.func, onBeforeSave:React.PropTypes.func, onAfterSave:React.PropTypes.func, onRevert:React.PropTypes.func, onDirtyChange:React.PropTypes.func }, loadPluginData:function(plugId){ PydioApi.getClient().request({ get_action:'get_plugin_manifest', plugin_id:plugId }, function(transport){ var xmlData = transport.responseXML; var params = PydioForm.Manager.parseParameters(xmlData, "//global_param"); var xmlValues = XMLUtils.XPathSelectNodes(xmlData, "//plugin_settings_values/param"); var documentation = XMLUtils.XPathSelectSingleNode(xmlData, "//plugin_doc"); var enabledAlways = false; var rootNode = XMLUtils.XPathSelectSingleNode(xmlData, "admin_data"); var label = rootNode.firstChild.attributes.getNamedItem("label").value; var description = rootNode.firstChild.attributes.getNamedItem("description").value; try{enabledAlways = rootNode.firstChild.attributes.getNamedItem("enabled").value === 'always';}catch (e){} var paramsValues = {}; xmlValues.forEach(function(child){ if(child.nodeName != 'param') return; var valueParamName = child.getAttribute("name"); if(child.getAttribute("cdatavalue")){ paramsValues[valueParamName] = child.firstChild.nodeValue; }else{ paramsValues[valueParamName] = child.getAttribute('value'); } var cType = null; params.map(function(def){ if(def.name == valueParamName) cType = def.type; }); if(cType == 'boolean') paramsValues[valueParamName] = (paramsValues[valueParamName] == "true"); else if(cType == 'integer') paramsValues[valueParamName] = parseInt(paramsValues[valueParamName]); }); this.setState({ loaded: true, parameters:params, values:paramsValues, originalValues:LangUtils.deepCopy(paramsValues), documentation:documentation, enabledAlways:enabledAlways, dirty:false, label:label, description:description, pluginId:plugId }); if(this.props.registerCloseCallback){ this.props.registerCloseCallback(function(){ if(this.state && this.state.dirty && !confirm(this.context.getMessage('19','role_editor'))){ return false; } }.bind(this)); } }.bind(this)); }, componentWillReceiveProps:function(nextProps){ if(nextProps.rootNode.getPath()!= this.props.rootNode.getPath()){ this.loadPluginData(PathUtils.getBasename(nextProps.rootNode.getPath())); this.setState({values:{}}); } }, getInitialState:function(){ var plugId = PathUtils.getBasename(this.props.rootNode.getPath()); this.loadPluginData(plugId); return { loaded:false, parameters:[], values:{}, documentation:'', dirty:false, label:'', docOpen:false }; }, externalSetDirty:function(){ this.setState({dirty:true}); }, onChange:function(formValues, dirty){ this.setState({dirty:dirty, values:formValues}); if(this.props.onDirtyChange){ this.props.onDirtyChange(dirty, formValues); } }, save:function(){ var clientParams = { get_action:"edit", sub_action:"edit_plugin_options", plugin_id:this.state.pluginId }; var postParams = this.refs['formPanel'].getValuesForPOST(this.state.values); if(postParams['DRIVER_OPTION_AJXP_PLUGIN_ENABLED']){ postParams['DRIVER_OPTION_AJXP_PLUGIN_ENABLED_ajxptype'] = "boolean"; } clientParams = LangUtils.mergeObjectsRecursive(clientParams, postParams); if(this.props.onBeforeSave){ this.props.onBeforeSave(clientParams); } PydioApi.getClient().request(clientParams, function(transport){ this.setState({dirty:false}); if(this.props.onAfterSave){ this.props.onAfterSave(transport); } }.bind(this)); }, revert:function(){ this.setState({dirty:false, values:this.state.originalValues}); if(this.props.onRevert){ this.props.onRevert(this.state.originalValues); } }, parameterHasHelper:function(paramName, testPluginId){ paramName = paramName.split('/').pop(); var h = PydioForm.Manager.hasHelper(PathUtils.getBasename(this.props.rootNode.getPath()), paramName); if(!h && testPluginId){ h = PydioForm.Manager.hasHelper(testPluginId, paramName); } return h; }, showHelper:function(helperData, testPluginId){ if(helperData){ var plugId = PathUtils.getBasename(this.props.rootNode.getPath()); if(testPluginId && !PydioForm.Manager.hasHelper(plugId, helperData['name'])){ helperData['pluginId'] = testPluginId; }else{ helperData['pluginId'] = plugId; } helperData['updateCallback'] = this.helperUpdateValues.bind(this); } this.setState({helperData:helperData}); }, closeHelper:function(){ this.setState({helperData:null}); }, /** * External helper can pass a full set of values and update them * @param newValues */ helperUpdateValues:function(newValues){ this.onChange(newValues, true); }, toggleDocPane: function(){ this.setState({docOpen:!this.state.docOpen}); }, monitorMainPaneScrolling:function(event){ if(event.target.className.indexOf('pydio-form-panel') === -1){ return; } var scroll = event.target.scrollTop; var newState = (scroll > 5); var currentScrolledState = (this.state && this.state.mainPaneScrolled); if(newState != currentScrolledState){ this.setState({mainPaneScrolled:newState}); } }, render: function(){ var addPanes = {top:[], bottom:[]}; if(this.props.additionalPanes){ addPanes.top = this.props.additionalPanes.top.slice(); addPanes.bottom = this.props.additionalPanes.bottom.slice(); } var closeButton; if(this.props.closeEditor){ closeButton = } var doc = this.state.documentation; if(doc && this.props.docAsAdditionalPane){ doc = doc.firstChild.nodeValue.replace('

', '').replace('

', ''); doc = doc.replace('

Documentation

); addPanes.top.push(docPane); } var scrollingClassName = ''; if(this.state && this.state.mainPaneScrolled){ scrollingClassName = ' main-pane-scrolled'; } // Building a form return (

{this.state.label}

       {closeButton}
{this.state.description} {this.props.additionalDescription}
); } }); export {PluginEditor as default}