kopia lustrzana https://github.com/OpenDroneMap/WebODM
Added addNewTaskPanelItem hook, proof of concept of state passing from NewTaskPanel to plugin
rodzic
9275325fe3
commit
912ed22c83
|
@ -2,7 +2,8 @@ export default {
|
|||
namespace: "Dashboard",
|
||||
|
||||
endpoints: [
|
||||
"addTaskActionButton"
|
||||
"addTaskActionButton",
|
||||
"addNewTaskPanelItem"
|
||||
]
|
||||
};
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ import $ from 'jquery';
|
|||
class EditTaskForm extends React.Component {
|
||||
static defaultProps = {
|
||||
selectedNode: null,
|
||||
task: null
|
||||
task: null,
|
||||
onFormChanged: () => {},
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
|
@ -20,6 +21,7 @@ class EditTaskForm extends React.Component {
|
|||
PropTypes.number
|
||||
]),
|
||||
onFormLoaded: PropTypes.func,
|
||||
onFormChanged: PropTypes.func,
|
||||
task: PropTypes.object
|
||||
};
|
||||
|
||||
|
@ -64,12 +66,18 @@ class EditTaskForm extends React.Component {
|
|||
this.getAvailableOptionsOnly = this.getAvailableOptionsOnly.bind(this);
|
||||
this.getAvailableOptionsOnlyText = this.getAvailableOptionsOnlyText.bind(this);
|
||||
this.saveLastPresetToStorage = this.saveLastPresetToStorage.bind(this);
|
||||
this.formReady = this.formReady.bind(this);
|
||||
}
|
||||
|
||||
formReady(){
|
||||
return this.state.loadedProcessingNodes &&
|
||||
this.state.selectedNode &&
|
||||
this.state.loadedPresets &&
|
||||
this.state.selectedPreset;
|
||||
}
|
||||
|
||||
notifyFormLoaded(){
|
||||
if (this.props.onFormLoaded &&
|
||||
this.state.loadedPresets &&
|
||||
this.state.loadedProcessingNodes) this.props.onFormLoaded();
|
||||
if (this.props.onFormLoaded && this.formReady()) this.props.onFormLoaded();
|
||||
}
|
||||
|
||||
loadProcessingNodes(){
|
||||
|
@ -273,6 +281,18 @@ class EditTaskForm extends React.Component {
|
|||
this.loadPresets();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState){
|
||||
// Monitor changes of certain form items (user driven)
|
||||
// and fire event when appropriate
|
||||
if (!this.formReady()) return;
|
||||
|
||||
let changed = false;
|
||||
['name', 'selectedNode', 'selectedPreset'].forEach(prop => {
|
||||
if (prevState[prop] !== this.state[prop]) changed = true;
|
||||
});
|
||||
if (changed) this.props.onFormChanged();
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
if (this.nodesRequest) this.nodesRequest.abort();
|
||||
if (this.presetsRequest) this.presetsRequest.abort();
|
||||
|
@ -457,10 +477,7 @@ class EditTaskForm extends React.Component {
|
|||
}
|
||||
|
||||
let taskOptions = "";
|
||||
if (this.state.loadedProcessingNodes &&
|
||||
this.state.selectedNode &&
|
||||
this.state.loadedPresets &&
|
||||
this.state.selectedPreset){
|
||||
if (this.formReady()){
|
||||
|
||||
taskOptions = (
|
||||
<div>
|
||||
|
|
|
@ -4,10 +4,10 @@ import EditTaskForm from './EditTaskForm';
|
|||
import PropTypes from 'prop-types';
|
||||
import Storage from '../classes/Storage';
|
||||
import ResizeModes from '../classes/ResizeModes';
|
||||
import update from 'immutability-helper';
|
||||
|
||||
class NewTaskPanel extends React.Component {
|
||||
static defaultProps = {
|
||||
name: "",
|
||||
filesCount: 0,
|
||||
showResize: false
|
||||
};
|
||||
|
@ -15,19 +15,20 @@ class NewTaskPanel extends React.Component {
|
|||
static propTypes = {
|
||||
onSave: PropTypes.func.isRequired,
|
||||
onCancel: PropTypes.func,
|
||||
name: PropTypes.string,
|
||||
filesCount: PropTypes.number,
|
||||
showResize: PropTypes.bool
|
||||
showResize: PropTypes.bool,
|
||||
getFiles: PropTypes.func
|
||||
};
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
name: props.name,
|
||||
editTaskFormLoaded: false,
|
||||
resizeMode: Storage.getItem('resize_mode') === null ? ResizeModes.YES : ResizeModes.fromString(Storage.getItem('resize_mode')),
|
||||
resizeSize: parseInt(Storage.getItem('resize_size')) || 2048
|
||||
resizeSize: parseInt(Storage.getItem('resize_size')) || 2048,
|
||||
items: [], // Coming from plugins,
|
||||
taskInfo: {}
|
||||
};
|
||||
|
||||
this.save = this.save.bind(this);
|
||||
|
@ -35,6 +36,17 @@ class NewTaskPanel extends React.Component {
|
|||
this.getTaskInfo = this.getTaskInfo.bind(this);
|
||||
this.setResizeMode = this.setResizeMode.bind(this);
|
||||
this.handleResizeSizeChange = this.handleResizeSizeChange.bind(this);
|
||||
this.handleFormChanged = this.handleFormChanged.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
PluginsAPI.Dashboard.triggerAddNewTaskPanelItem({}, (item) => {
|
||||
if (!item) return;
|
||||
|
||||
this.setState(update(this.state, {
|
||||
items: {$push: [item]}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
save(e){
|
||||
|
@ -77,6 +89,10 @@ class NewTaskPanel extends React.Component {
|
|||
this.setState({editTaskFormLoaded: true});
|
||||
}
|
||||
|
||||
handleFormChanged(){
|
||||
this.setState({taskInfo: this.getTaskInfo()});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="new-task-panel theme-background-highlight">
|
||||
|
@ -84,38 +100,46 @@ class NewTaskPanel extends React.Component {
|
|||
<p>{this.props.filesCount} files selected. Please check these additional options:</p>
|
||||
<EditTaskForm
|
||||
onFormLoaded={this.handleFormTaskLoaded}
|
||||
onFormChanged={this.handleFormChanged}
|
||||
ref={(domNode) => { if (domNode) this.taskForm = domNode; }}
|
||||
/>
|
||||
|
||||
{this.state.editTaskFormLoaded ?
|
||||
<div className="form-group">
|
||||
<label className="col-sm-2 control-label">Resize Images</label>
|
||||
<div className="col-sm-10">
|
||||
<div className="btn-group">
|
||||
<button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
{ResizeModes.toHuman(this.state.resizeMode)} <span className="caret"></span>
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
{ResizeModes.all().map(mode =>
|
||||
<li key={mode}>
|
||||
<a href="javascript:void(0);"
|
||||
onClick={this.setResizeMode(mode)}>
|
||||
<i style={{opacity: this.state.resizeMode === mode ? 1 : 0}} className="fa fa-check"></i> {ResizeModes.toHuman(mode)}</a>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div className={"resize-control " + (this.state.resizeMode === ResizeModes.NO ? "hide" : "")}>
|
||||
<input
|
||||
type="number"
|
||||
step="100"
|
||||
className="form-control"
|
||||
onChange={this.handleResizeSizeChange}
|
||||
value={this.state.resizeSize}
|
||||
/>
|
||||
<span>px</span>
|
||||
<div>
|
||||
<div className="form-group">
|
||||
<label className="col-sm-2 control-label">Resize Images</label>
|
||||
<div className="col-sm-10">
|
||||
<div className="btn-group">
|
||||
<button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
{ResizeModes.toHuman(this.state.resizeMode)} <span className="caret"></span>
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
{ResizeModes.all().map(mode =>
|
||||
<li key={mode}>
|
||||
<a href="javascript:void(0);"
|
||||
onClick={this.setResizeMode(mode)}>
|
||||
<i style={{opacity: this.state.resizeMode === mode ? 1 : 0}} className="fa fa-check"></i> {ResizeModes.toHuman(mode)}</a>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div className={"resize-control " + (this.state.resizeMode === ResizeModes.NO ? "hide" : "")}>
|
||||
<input
|
||||
type="number"
|
||||
step="100"
|
||||
className="form-control"
|
||||
onChange={this.handleResizeSizeChange}
|
||||
value={this.state.resizeSize}
|
||||
/>
|
||||
<span>px</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.state.items.map((Item, i) => <div key={i} className="form-group">
|
||||
<Item taskInfo={this.state.taskInfo}
|
||||
getFiles={this.props.getFiles}
|
||||
/>
|
||||
</div>)}
|
||||
</div>
|
||||
: ""}
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ class ProjectListItem extends React.Component {
|
|||
resizedImages: 0,
|
||||
error: "",
|
||||
progress: 0,
|
||||
files: [],
|
||||
totalCount: 0,
|
||||
totalBytes: 0,
|
||||
totalBytesSent: 0,
|
||||
|
@ -169,7 +170,8 @@ class ProjectListItem extends React.Component {
|
|||
.on("addedfiles", files => {
|
||||
this.setUploadState({
|
||||
editing: true,
|
||||
totalCount: this.state.upload.totalCount + files.length
|
||||
totalCount: this.state.upload.totalCount + files.length,
|
||||
files
|
||||
});
|
||||
})
|
||||
.on("transformcompleted", (file, total) => {
|
||||
|
@ -430,6 +432,7 @@ class ProjectListItem extends React.Component {
|
|||
onCancel={this.handleTaskCanceled}
|
||||
filesCount={this.state.upload.totalCount}
|
||||
showResize={true}
|
||||
getFiles={() => this.state.upload.files }
|
||||
/>
|
||||
: ""}
|
||||
|
||||
|
|
|
@ -21,6 +21,12 @@ class Plugin(PluginBase):
|
|||
def main_menu(self):
|
||||
return [Menu("Lightning Network", self.public_url(""), "fa fa-bolt fa-fw")]
|
||||
|
||||
def include_js_files(self):
|
||||
return ['add_cost_estimate.js']
|
||||
|
||||
def build_jsx_components(self):
|
||||
return ['app.jsx', 'CostEstimateItem.jsx']
|
||||
|
||||
def app_mount_points(self):
|
||||
@login_required
|
||||
def main(request):
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import './CostEstimateItem.scss';
|
||||
import PropTypes from 'prop-types';
|
||||
import $ from 'jquery';
|
||||
|
||||
export default class CostEstimateItem extends React.Component {
|
||||
static defaultProps = {
|
||||
};
|
||||
static propTypes = {
|
||||
}
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="lightning-cost-estimate-item">
|
||||
<label className="col-sm-2 control-label">Credits Required</label>
|
||||
<div className="col-sm-10 num-credits">
|
||||
{this.props.taskInfo.name}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
.lightning-cost-estimate-item{
|
||||
.num-credits{
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
PluginsAPI.Dashboard.addNewTaskPanelItem([
|
||||
'lightning/build/CostEstimateItem.js',
|
||||
'lightning/build/CostEstimateItem.css',
|
||||
],function(args, CostEstimateItem){
|
||||
return CostEstimateItem;
|
||||
});
|
Ładowanie…
Reference in New Issue