EditTaskForm steps state and style

pull/1488/head
0thigs 2024-04-15 15:48:16 -03:00
rodzic ebce3e9329
commit 32ffd09908
2 zmienionych plików z 301 dodań i 248 usunięć

Wyświetl plik

@ -14,23 +14,23 @@ class EditTaskForm extends React.Component {
static defaultProps = {
selectedNode: null,
task: null,
onFormChanged: () => {},
inReview: false
onFormChanged: () => { },
inReview: false,
};
static propTypes = {
selectedNode: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
onFormLoaded: PropTypes.func,
onFormChanged: PropTypes.func,
inReview: PropTypes.bool,
task: PropTypes.object,
suggestedTaskName: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
selectedNode: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
onFormLoaded: PropTypes.func,
onFormChanged: PropTypes.func,
inReview: PropTypes.bool,
task: PropTypes.object,
suggestedTaskName: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
};
constructor(props){
constructor(props) {
super(props);
this.state = {
@ -48,6 +48,9 @@ class EditTaskForm extends React.Component {
presets: [],
tags: props.task !== null ? Utils.clone(props.task.tags) : [],
steps: ["settingsStep", "aiStep", "loadingStep"],
isPopupOpen: false,
editingPreset: false,
loadingTaskName: false,
@ -78,51 +81,51 @@ class EditTaskForm extends React.Component {
this.formReady = this.formReady.bind(this);
}
formReady(){
return this.state.loadedProcessingNodes &&
this.state.selectedNode &&
this.state.loadedPresets &&
this.state.selectedPreset;
formReady() {
return this.state.loadedProcessingNodes &&
this.state.selectedNode &&
this.state.loadedPresets &&
this.state.selectedPreset;
}
checkFilesCount(filesCount){
checkFilesCount(filesCount) {
if (!this.state.selectedNode) return true;
if (filesCount === 0) return true;
if (this.state.selectedNode.max_images === null) return true;
return this.state.selectedNode.max_images >= filesCount;
}
selectedNodeMaxImages(){
selectedNodeMaxImages() {
if (!this.state.selectedNode) return null;
return this.state.selectedNode.max_images;
}
notifyFormLoaded(){
notifyFormLoaded() {
if (this.props.onFormLoaded && this.formReady()) this.props.onFormLoaded();
}
firstEnabledNode(){
for (let i = 0; i < this.state.processingNodes.length; i++){
if (this.state.processingNodes[i].enabled) return this.state.processingNodes[i];
}
return null;
firstEnabledNode() {
for (let i = 0; i < this.state.processingNodes.length; i++) {
if (this.state.processingNodes[i].enabled) return this.state.processingNodes[i];
}
return null;
}
loadProcessingNodes(){
loadProcessingNodes() {
const failed = () => {
this.setState({error: _("Could not load list of processing nodes. Are you connected to the internet?")});
this.setState({ error: _("Could not load list of processing nodes. Are you connected to the internet?") });
}
this.nodesRequest =
this.nodesRequest =
$.getJSON("/api/processingnodes/?has_available_options=True", json => {
if (Array.isArray(json)){
if (Array.isArray(json)) {
// No nodes with options?
const noProcessingNodesError = (nodes) => {
var extra = nodes ? _("We tried to reach:") + "<ul>" + nodes.map(n => Utils.html`<li><a href="${n.url}">${n.label}</a></li>`).join("") + "</ul>" : "";
this.setState({error: _("There are no usable processing nodes.") + extra + _("Make sure that at least one processing node is reachable and that you have granted the current user sufficient permissions to view the processing node (by going to Administration -- Processing Nodes -- Select Node -- Object Permissions -- Add User/Group and check CAN VIEW PROCESSING NODE). If you are bringing a node back online, it will take about 30 seconds for WebODM to recognize it.")});
this.setState({ error: _("There are no usable processing nodes.") + extra + _("Make sure that at least one processing node is reachable and that you have granted the current user sufficient permissions to view the processing node (by going to Administration -- Processing Nodes -- Select Node -- Object Permissions -- Add User/Group and check CAN VIEW PROCESSING NODE). If you are bringing a node back online, it will take about 30 seconds for WebODM to recognize it.") });
};
if (json.length === 0){
if (json.length === 0) {
noProcessingNodesError();
return;
}
@ -144,66 +147,66 @@ class EditTaskForm extends React.Component {
let minQueueCount = Math.min(...nodes.filter(node => node.enabled).map(node => node.queue_count));
let minQueueCountNodes = nodes.filter(node => node.enabled && node.queue_count === minQueueCount);
if (minQueueCountNodes.length === 0){
if (minQueueCountNodes.length === 0) {
noProcessingNodesError(nodes);
return;
}
// Choose at random
let lowestQueueNode = minQueueCountNodes[~~(Math.random() * minQueueCountNodes.length)];
this.setState({
processingNodes: nodes,
loadedProcessingNodes: true
});
// Have we specified a node?
if (this.props.task && this.props.task.processing_node){
if (this.props.task.auto_processing_node){
if (this.props.task && this.props.task.processing_node) {
if (this.props.task.auto_processing_node) {
this.selectNodeByKey(lowestQueueNode.key);
}else{
} else {
this.selectNodeByKey(this.props.task.processing_node);
}
}else if (this.props.selectedNode){
} else if (this.props.selectedNode) {
this.selectNodeByKey(this.props.selectedNode);
}else{
} else {
this.selectNodeByKey(lowestQueueNode.key);
}
this.notifyFormLoaded();
}else{
} else {
console.error("Got invalid json response for processing nodes", json);
failed();
}
})
.fail((jqXHR, textStatus, errorThrown) => {
// I don't expect this to fail, unless it's a development error or connection error.
// in which case we don't need to notify the user directly.
failed();
});
.fail((jqXHR, textStatus, errorThrown) => {
// I don't expect this to fail, unless it's a development error or connection error.
// in which case we don't need to notify the user directly.
failed();
});
}
retryLoad(){
this.setState({error: ""});
retryLoad() {
this.setState({ error: "" });
this.loadProcessingNodes();
this.loadPresets();
}
findFirstPresetMatching(presets, options){
for (let i = 0; i < presets.length; i++){
findFirstPresetMatching(presets, options) {
for (let i = 0; i < presets.length; i++) {
const preset = presets[i];
if (options.length === preset.options.length){
if (options.length === preset.options.length) {
let dict = {};
options.forEach(opt => {
dict[opt.name] = opt.value;
});
let matchingOptions = 0;
for (let j = 0; j < preset.options.length; j++){
if (dict[preset.options[j].name] !== preset.options[j].value){
for (let j = 0; j < preset.options.length; j++) {
if (dict[preset.options[j].name] !== preset.options[j].value) {
break;
}else{
} else {
matchingOptions++;
}
}
@ -216,14 +219,14 @@ class EditTaskForm extends React.Component {
return null;
}
loadPresets(){
loadPresets() {
const failed = () => {
this.setState({error: _("Could not load list of presets. Are you connected to the internet?")});
this.setState({ error: _("Could not load list of presets. Are you connected to the internet?") });
}
this.presetsRequest =
this.presetsRequest =
$.getJSON("/api/presets/?ordering=-system,-created_at", presets => {
if (Array.isArray(presets)){
if (Array.isArray(presets)) {
// Add custom preset
const customPreset = {
id: -1,
@ -236,139 +239,139 @@ class EditTaskForm extends React.Component {
// Choose preset
_("Default"); // Add translation
let selectedPreset = presets[0],
defaultPreset = presets.find(p => p.name === "Default"); // Do not translate Default
defaultPreset = presets.find(p => p.name === "Default"); // Do not translate Default
if (defaultPreset) selectedPreset = defaultPreset;
// If task's options are set attempt
// to find a preset that matches the current task options
if (this.props.task && Array.isArray(this.props.task.options) && this.props.task.options.length > 0){
if (this.props.task && Array.isArray(this.props.task.options) && this.props.task.options.length > 0) {
const taskPreset = this.findFirstPresetMatching(presets, this.props.task.options);
if (taskPreset !== null){
if (taskPreset !== null) {
selectedPreset = taskPreset;
}else{
} else {
customPreset.options = Utils.clone(this.props.task.options);
selectedPreset = customPreset;
}
}else{
} else {
// Check local storage for last used preset
const lastPresetId = Storage.getItem("last_preset_id");
if (lastPresetId !== null){
if (lastPresetId !== null) {
const lastPreset = presets.find(p => p.id == lastPresetId);
if (lastPreset) selectedPreset = lastPreset;
}
}
this.setState({
loadedPresets: true,
presets: presets,
loadedPresets: true,
presets: presets,
selectedPreset: selectedPreset
});
this.notifyFormLoaded();
}else{
} else {
console.error("Got invalid json response for presets", json);
failed();
}
})
.fail((jqXHR, textStatus, errorThrown) => {
// I don't expect this to fail, unless it's a development error or connection error.
// in which case we don't need to notify the user directly.
failed();
});
.fail((jqXHR, textStatus, errorThrown) => {
// I don't expect this to fail, unless it's a development error or connection error.
// in which case we don't need to notify the user directly.
failed();
});
}
loadSuggestedName = () => {
if (typeof this.props.suggestedTaskName === "function"){
this.setState({loadingTaskName: true});
if (typeof this.props.suggestedTaskName === "function") {
this.setState({ loadingTaskName: true });
this.props.suggestedTaskName().then(name => {
if (this.state.loadingTaskName){
this.setState({loadingTaskName: false, name});
}else{
// User started typing its own name
}
}).catch(e => {
// Do Nothing
this.setState({loadingTaskName: false});
})
this.props.suggestedTaskName().then(name => {
if (this.state.loadingTaskName) {
this.setState({ loadingTaskName: false, name });
} else {
// User started typing its own name
}
}).catch(e => {
// Do Nothing
this.setState({ loadingTaskName: false });
})
}
}
handleSelectPreset(e){
handleSelectPreset(e) {
this.selectPresetById(e.target.value);
}
selectPresetById(id){
selectPresetById(id) {
let preset = this.state.presets.find(p => p.id === parseInt(id));
if (preset) this.setState({selectedPreset: preset});
if (preset) this.setState({ selectedPreset: preset });
}
componentDidMount(){
componentDidMount() {
this.loadProcessingNodes();
this.loadPresets();
this.loadSuggestedName();
}
componentDidUpdate(prevProps, prevState){
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 (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();
componentWillUnmount() {
if (this.nodesRequest) this.nodesRequest.abort();
if (this.presetsRequest) this.presetsRequest.abort();
}
handleNameChange(e){
this.setState({name: e.target.value, loadingTaskName: false});
handleNameChange(e) {
this.setState({ name: e.target.value, loadingTaskName: false });
}
selectNodeByKey(key){
selectNodeByKey(key) {
let node = this.state.processingNodes.find(node => node.key == key);
if (node) this.setState({selectedNode: node});
else{
console.log(`Node ${key} does not exist, selecting first enabled`);
const n = this.firstEnabledNode();
if (n){
this.selectNodeByKey(n.key);
}
if (node) this.setState({ selectedNode: node });
else {
console.log(`Node ${key} does not exist, selecting first enabled`);
const n = this.firstEnabledNode();
if (n) {
this.selectNodeByKey(n.key);
}
}
}
handleSelectNode(e){
handleSelectNode(e) {
this.selectNodeByKey(e.target.value);
}
// Filter a list of options based on the ones that
// are available (usually options are from a preset and availableOptions
// from a processing node)
getAvailableOptionsOnly(options, availableOptions){
getAvailableOptionsOnly(options, availableOptions) {
const optionNames = {};
availableOptions.forEach(opt => optionNames[opt.name] = true);
return options.filter(opt => optionNames[opt.name]);
}
getAvailableOptionsOnlyText(options, availableOptions){
getAvailableOptionsOnlyText(options, availableOptions) {
const opts = this.getAvailableOptionsOnly(options, availableOptions);
let res = opts.map(opt => `${opt.name}:${opt.value}`).join(", ");
if (!res) res = _("Default");
return res;
}
saveLastPresetToStorage(){
if (this.state.selectedPreset){
saveLastPresetToStorage() {
if (this.state.selectedPreset) {
Storage.setItem('last_preset_id', this.state.selectedPreset.id);
}
}
getTaskInfo(){
getTaskInfo() {
const { name, selectedNode, selectedPreset, tags } = this.state;
return {
@ -379,15 +382,15 @@ class EditTaskForm extends React.Component {
};
}
handleEditPreset(){
handleEditPreset() {
// If the user tries to edit a system preset
// set the "Custom..." options to it
const { selectedPreset, presets } = this.state;
if (selectedPreset.system){
if (selectedPreset.system) {
let customPreset = presets.find(p => p.id === -1);
// Might have been deleted
if (!customPreset){
if (!customPreset) {
customPreset = {
id: -1,
name: "(" + _("Custom") + ")",
@ -395,34 +398,34 @@ class EditTaskForm extends React.Component {
system: true
};
presets.unshift(customPreset);
this.setState({presets});
this.setState({ presets });
}
customPreset.options = Utils.clone(selectedPreset.options);
this.setState({selectedPreset: customPreset});
this.setState({ selectedPreset: customPreset });
}
this.setState({editingPreset: true});
this.setState({ editingPreset: true });
}
handleCancelEditPreset(){
this.setState({editingPreset: false});
handleCancelEditPreset() {
this.setState({ editingPreset: false });
}
handlePresetSave(preset){
handlePresetSave(preset) {
const done = () => {
// Update presets and selected preset
let p = this.state.presets.find(p => p.id === preset.id);
p.name = preset.name;
p.options = preset.options;
this.setState({selectedPreset: p});
this.setState({ selectedPreset: p });
};
// If it's a custom preset do not update server-side
if (preset.id === -1){
if (preset.id === -1) {
done();
return $.Deferred().resolve();
}else{
} else {
return $.ajax({
url: `/api/presets/${preset.id}/`,
contentType: 'application/json',
@ -436,14 +439,14 @@ class EditTaskForm extends React.Component {
}
}
handleDuplicateSavePreset(){
handleDuplicateSavePreset() {
// Create a new preset with the same settings as the
// currently selected preset
const { selectedPreset, presets } = this.state;
this.setState({presetActionPerforming: true});
this.setState({ presetActionPerforming: true });
const isCustom = selectedPreset.id === -1,
name = isCustom ? _("My Preset") : interpolate(_("Copy of %(preset)s"), {preset: selectedPreset.name});
name = isCustom ? _("My Preset") : interpolate(_("Copy of %(preset)s"), { preset: selectedPreset.name });
$.ajax({
url: `/api/presets/`,
@ -457,30 +460,30 @@ class EditTaskForm extends React.Component {
}).done(preset => {
// If the original preset was a custom one,
// we remove it from the list (since we just saved it)
if (isCustom){
if (isCustom) {
presets.splice(presets.indexOf(selectedPreset), 1);
}
// Add new preset to list, select it, then edit
presets.push(preset);
this.setState({presets, selectedPreset: preset});
this.setState({ presets, selectedPreset: preset });
this.handleEditPreset();
}).fail(() => {
this.setState({presetError: _("Could not duplicate the preset. Please try to refresh the page.")});
this.setState({ presetError: _("Could not duplicate the preset. Please try to refresh the page.") });
}).always(() => {
this.setState({presetActionPerforming: false});
this.setState({ presetActionPerforming: false });
});
}
handleDeletePreset(){
handleDeletePreset() {
const { selectedPreset, presets } = this.state;
if (selectedPreset.system){
this.setState({presetError: _("System presets can only be removed by a staff member from the Administration panel.")});
if (selectedPreset.system) {
this.setState({ presetError: _("System presets can only be removed by a staff member from the Administration panel.") });
return;
}
if (window.confirm(interpolate(_('Are you sure you want to delete "%(preset)s"?'), { preset: selectedPreset.name}))){
this.setState({presetActionPerforming: true});
if (window.confirm(interpolate(_('Are you sure you want to delete "%(preset)s"?'), { preset: selectedPreset.name }))) {
this.setState({ presetActionPerforming: true });
return $.ajax({
url: `/api/presets/${selectedPreset.id}/`,
@ -490,97 +493,98 @@ class EditTaskForm extends React.Component {
presets.splice(presets.indexOf(selectedPreset), 1);
// Select first by default
this.setState({presets, selectedPreset: presets[0], editingPreset: false});
this.setState({ presets, selectedPreset: presets[0], editingPreset: false });
}).fail(() => {
this.setState({presetError: _("Could not delete the preset. Please try to refresh the page.")});
this.setState({ presetError: _("Could not delete the preset. Please try to refresh the page.") });
}).always(() => {
this.setState({presetActionPerforming: false});
this.setState({ presetActionPerforming: false });
});
}else{
} else {
return $.Deferred().resolve();
}
}
toggleTagsField = () => {
if (!this.state.showTagsField){
if (!this.state.showTagsField) {
setTimeout(() => {
if (this.tagsField) this.tagsField.focus();
}, 0);
}
this.setState({showTagsField: !this.state.showTagsField});
this.setState({ showTagsField: !this.state.showTagsField });
}
render() {
if (this.state.error){
if (this.state.error) {
return (<div className="edit-task-panel">
<div className="alert alert-warning">
<div dangerouslySetInnerHTML={{__html:this.state.error}}></div>
<button className="btn btn-sm btn-primary" onClick={this.retryLoad}>
<i className="fa fa-rotate-left"></i> {_("Retry")}
</button>
</div>
</div>);
<div className="alert alert-warning">
<div dangerouslySetInnerHTML={{ __html: this.state.error }}></div>
<button className="btn btn-sm btn-primary" onClick={this.retryLoad}>
<i className="fa fa-rotate-left"></i> {_("Retry")}
</button>
</div>
</div>);
}
let taskOptions = "";
if (this.formReady()){
let iaOptions = "";
if (this.formReady()) {
const optionsSelector = (
<div className='select-container'>
<select
<div className='select-container' style={{ display: "flex", justifyContent: "start", alignItems: "center", }}>
<select
title={this.getAvailableOptionsOnlyText(this.state.selectedPreset.options, this.state.selectedNode.options)}
className="form-control input-field"
value={this.state.selectedPreset.id}
className="form-control input-field"
value={this.state.selectedPreset.id}
onChange={this.handleSelectPreset}>
{this.state.presets.map(preset =>
<option value={preset.id} key={preset.id} className={preset.system ? "system-preset" : ""}>{preset.name === "Default" ? _(preset.name) : preset.name}</option>
)}
</select>
{this.state.presets.map(preset =>
<option value={preset.id} key={preset.id} className={preset.system ? "system-preset" : ""}>{preset.name === "Default" ? _(preset.name) : preset.name}</option>
)}
</select>
{!this.state.presetActionPerforming ?
<div className="btn-group presets-dropdown">
<button type="button" className="btn btn-sm btn-default" title={_("Edit Task Options")} onClick={this.handleEditPreset}>
<i className="fa fa-sliders-h"></i> {_("Edit")}
</button>
<button type="button" className="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
{!this.state.presetActionPerforming ?
<div className="btn-group presets-dropdown">
<button type="button" className="btn btn-sm btn-default" title={_("Edit Task Options")} onClick={this.handleEditPreset}>
<i className="fa fa-sliders-h"></i> {_("Edit")}
</button>
<button type="button" className="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
<span className="caret"></span>
</button>
<ul className="dropdown-menu">
<li>
<a href="javascript:void(0);" onClick={this.handleEditPreset}><i className="fa fa-sliders-h"></i> {_("Edit")}</a>
</li>
<li className="divider"></li>
</button>
<ul className="dropdown-menu">
<li>
<a href="javascript:void(0);" onClick={this.handleEditPreset}><i className="fa fa-sliders-h"></i> {_("Edit")}</a>
</li>
<li className="divider"></li>
{this.state.selectedPreset.id !== -1 ?
<li>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-copy"></i> {_("Duplicate")}</a>
{this.state.selectedPreset.id !== -1 ?
<li>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-copy"></i> {_("Duplicate")}</a>
</li>
:
<li>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-save"></i> {_("Save")}</a>
</li>
}
<li className={this.state.selectedPreset.system ? "disabled" : ""}>
<a href="javascript:void(0);" onClick={this.handleDeletePreset}><i className="fa fa-trash"></i> {_("Delete")}</a>
</li>
:
<li>
<a href="javascript:void(0);" onClick={this.handleDuplicateSavePreset}><i className="fa fa-save"></i> {_("Save")}</a>
</li>
}
<li className={this.state.selectedPreset.system ? "disabled" : ""}>
<a href="javascript:void(0);" onClick={this.handleDeletePreset}><i className="fa fa-trash"></i> {_("Delete")}</a>
</li>
</ul>
</div>
: <i className="preset-performing-action-icon fa fa-cog fa-spin fa-fw"></i>}
<ErrorMessage className="preset-error" bind={[this, 'presetError']} />
</div>);
</ul>
</div>
: <i className="preset-performing-action-icon fa fa-cog fa-spin fa-fw"></i>}
<ErrorMessage className="preset-error" bind={[this, 'presetError']} />
</div>);
let tagsField = "";
if (this.state.showTagsField){
if (this.state.showTagsField) {
tagsField = (<div className="form-group">
<label className="col-sm-2 control-label">{_("Tags")}</label>
<div className="col-sm-10">
<TagsField onUpdate={(tags) => this.state.tags = tags } tags={this.state.tags} ref={domNode => this.tagsField = domNode}/>
</div>
</div>);
<label className="col-sm-2 control-label">{_("Tags")}</label>
<div className="col-sm-10">
<TagsField onUpdate={(tags) => this.state.tags = tags} tags={this.state.tags} ref={domNode => this.tagsField = domNode} />
</div>
</div>);
}
taskOptions = (
<div>
<div className='edit-task-form'>
{tagsField}
{/* <div className="form-group col-sm-10 form-group-data">
<label className="col-sm-2 control-label">{_("Processing Node")}</label>
@ -592,60 +596,91 @@ class EditTaskForm extends React.Component {
</select>
</div>
</div> */}
<div className="form-group form-inline">
<label className="col-sm-2 control-label">{_("Options")}</label>
<div className="col-sm-10 option-container">
{!this.props.inReview ? optionsSelector :
<div className="review-options">
{this.getAvailableOptionsOnlyText(this.state.selectedPreset.options, this.state.selectedNode.options)}
</div>}
</div>
<div className='form-group pad-this'>
<label className="col-sm-2 control-label">{_("Data")}</label>
<input type="text" className="col-sm-10 input-field data-input"/>
</div>
</div>
{this.state.editingPreset ?
<EditPresetDialog
preset={this.state.selectedPreset}
availableOptions={this.state.selectedNode.options}
onHide={this.handleCancelEditPreset}
saveAction={this.handlePresetSave}
deleteAction={this.handleDeletePreset}
ref={(domNode) => { if (domNode) this.editPresetDialog = domNode; }}
/>
: ""}
</div>
);
}else{
taskOptions = (<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">{_("Loading processing nodes and presets...")} <i className="fa fa-sync fa-spin fa-fw"></i></div>
</div>);
}
return (
<div className="edit-task-form">
<div className="form-group col-sm-10">
<label className="col-sm-2 control-label">{_("Name")}</label>
<div className="form-group col-sm-10">
<label className="col-sm-2 control-label">{_("Name")}</label>
<div className="col-sm-10 name-fields input-field">
{this.state.loadingTaskName ?
<i className="fa fa-circle-notch fa-spin fa-fw name-loading"></i>
: ""}
<input type="text"
onChange={this.handleNameChange}
{this.state.loadingTaskName ?
<i className="fa fa-circle-notch fa-spin fa-fw name-loading"></i>
: ""}
<input type="text"
onChange={this.handleNameChange}
className="remove-style name-input"
placeholder={this.state.namePlaceholder}
value={this.state.name}/>
placeholder={this.state.namePlaceholder}
value={this.state.name} />
<button type="button" title={_("Add tags")} onClick={this.toggleTagsField} className="remove-style">
<i className="fa fa-tag"></i>
</button>
</div>
</div>
</div>
{taskOptions}
</div>
{/* <div>
<label className="col-sm-2 control-label">{_("Options")}</label>
<div className="col-sm-10 option-container">
{!this.props.inReview ? optionsSelector :
<div className="review-options">
{this.getAvailableOptionsOnlyText(this.state.selectedPreset.options, this.state.selectedNode.options)}
</div>}
</div>
</div> */}
<div className='form-group col-sm-10'>
<label className="col-sm-2 control-label">{_("Data")}</label>
<div className="col-sm-10 option-container">
<input type="text" className="col-sm-10 input-field data-input" />
</div>
</div>
{
this.state.editingPreset ?
<EditPresetDialog
preset={this.state.selectedPreset}
availableOptions={this.state.selectedNode.options}
onHide={this.handleCancelEditPreset}
saveAction={this.handlePresetSave}
deleteAction={this.handleDeletePreset}
ref={(domNode) => { if (domNode) this.editPresetDialog = domNode; }}
/>
: ""
}
</div >);
} else {
taskOptions = (<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">{_("Loading processing nodes and presets...")} <i className="fa fa-sync fa-spin fa-fw"></i></div>
</div>);
}
return (
<>
{/* Task Information Panel */}
{this.props.currentStep === "settingsStep" && <div>{taskOptions}</div>}
{/* Ai Panel */}
{this.props.currentStep === "aiStep" && <div>
<div className='edit-task-form'>
<div className="form-group">
<label className="col-sm-2 control-label ai-label">{_("Detecção de Daninhas e Obstáculos com IA:")}</label>
<select className='btn btn-default-s selectBtn dropdown-toggle' style={{ backgroundColor: "#74B16F" }}>
<option>Sim</option>
<option>Não</option>
</select>
</div>
<div className='form-group'>
<label className="col-sm-2 control-label ai-label">{_("Geração de Arquivos")}</label>
<button className='btn btn-default-s selectBtn dropdown-toggle'>Uso em Drones</button>
</div>
<div className="form-group">
<label className="col-sm-2 control-label ai-label" >{_("Detecção de Subtalhões:")}</label>
<select className='btn btn-default-s selectBtn dropdown-toggle' style={{ backgroundColor: "#74B16F" }}>
<option>Sim</option>
<option>Não</option>
</select>
</div>
</div >
</div>}
{/* Loading Panel */}
{this.props.currentStep === "loadingStep" && <div></div>}
</>
);
}
}

Wyświetl plik

@ -49,20 +49,38 @@
.form-group {
width: 100%;
.select-container {
display: flex;
}
.option-container {
padding: 0 15px 0 7px;
}
@media (max-width: 600px) {
.option-container {
padding: 0px 15px;
}
padding: 0;
}
.pad-this {
padding: 0 30px;
}
.selectBtn {
display: flex;
justify-content: center;
align-items: center;
text-decoration: none;
background-position: calc(100% - 0.75rem) center !important;
-moz-appearance:none !important;
-webkit-appearance: none !important;
appearance: none !important;
}
.ai-label {
width: 400px;
@media (max-width: 600px) {
.ai-label {
}
}
}
}
.form-group-data {