kopia lustrzana https://github.com/OpenDroneMap/WebODM
Translated some plugins
rodzic
4946609a94
commit
d1b15c0077
|
@ -3,6 +3,7 @@ import './CostEstimateItem.scss';
|
|||
import ResizeModes from 'webodm/classes/ResizeModes';
|
||||
import PropTypes from 'prop-types';
|
||||
import $ from 'jquery';
|
||||
import { _ } from 'webodm/classes/gettext';
|
||||
|
||||
export default class CostEstimateItem extends React.Component {
|
||||
static defaultProps = {
|
||||
|
@ -99,10 +100,10 @@ export default class CostEstimateItem extends React.Component {
|
|||
if (json.credits_estimate === 0) json.credits_estimate += " (Free)";
|
||||
this.setState({credits: json.credits_estimate})
|
||||
}else{
|
||||
this.setState({credits: "Cannot retrieve estimate. Try again later."});
|
||||
this.setState({credits: _("Cannot retrieve estimate. Try again later.")});
|
||||
}
|
||||
}).fail(e => {
|
||||
this.setState({credits: `Cannot retrieve estimate. Check parameters or try again later.`});
|
||||
this.setState({credits: _("Cannot retrieve estimate. Check parameters or try again later.")});
|
||||
}).always(() => {
|
||||
this.setState({loading: false});
|
||||
this.estimateRequest = null;
|
||||
|
@ -135,7 +136,7 @@ export default class CostEstimateItem extends React.Component {
|
|||
|
||||
return (
|
||||
<div className={"lightning-cost-estimate-item " + (show ? "" : "hide")}>
|
||||
<label className="col-sm-2 control-label">Credits Estimate</label>
|
||||
<label className="col-sm-2 control-label">{_("Credits Estimate")}</label>
|
||||
<div className="col-sm-10 num-credits">
|
||||
{loading ?
|
||||
<i className="fa fa-circle-notch fa-spin"></i> :
|
||||
|
|
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
|||
import './Dashboard.scss';
|
||||
import $ from 'jquery';
|
||||
import { _ } from 'webodm/classes/gettext';
|
||||
import Trans from 'webodm/components/Trans';
|
||||
|
||||
export default class Dashboard extends React.Component {
|
||||
static defaultProps = {
|
||||
|
@ -44,11 +45,11 @@ export default class Dashboard extends React.Component {
|
|||
}else if (json.message === "Unauthorized"){
|
||||
this.props.onLogout();
|
||||
}else{
|
||||
this.setState({ loading: false, error: `Cannot load lightning dashboard. Server responded: ${JSON.stringify(json)}. Are you running the latest version of WebODM?` });
|
||||
this.setState({ loading: false, error: _('Cannot load lightning dashboard. Are you running the latest version of WebODM?') });
|
||||
}
|
||||
})
|
||||
.fail(() => {
|
||||
this.setState({ loading: false, error: `Cannot load lightning dashboard. Please make sure you are connected to the internet, or try again in an hour.`});
|
||||
this.setState({ loading: false, error: _('Cannot load lightning dashboard. Please make sure you are connected to the internet, or try again in an hour.')});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,7 @@ export default class Dashboard extends React.Component {
|
|||
}
|
||||
})
|
||||
.fail(e => {
|
||||
this.setState({error: `Cannot sync nodes: ${JSON.stringify(e)}. Are you connected to the internet?`});
|
||||
this.setState({error: _('Cannot sync nodes. Are you connected to the internet?')});
|
||||
})
|
||||
.always(() => {
|
||||
this.setState({syncingNodes: false});
|
||||
|
@ -79,18 +80,18 @@ export default class Dashboard extends React.Component {
|
|||
}
|
||||
|
||||
handeLogout = () => {
|
||||
this.setState({loading: true, loadingMessage: "Logging out..."});
|
||||
this.setState({loading: true, loadingMessage: _('Logging out…')});
|
||||
|
||||
$.post("save_api_key", {
|
||||
api_key: ""
|
||||
}).done(json => {
|
||||
if (!json.success){
|
||||
this.setState({error: `Cannot logout: ${JSON.stringify(json)}`});
|
||||
this.setState({error: `${_("Cannot logout:")} ${JSON.stringify(json)}`});
|
||||
}
|
||||
this.setState({loading: false});
|
||||
this.props.onLogout();
|
||||
}).fail(e => {
|
||||
this.setState({loading: false, error: `Cannot logout: ${JSON.stringify(e)}`});
|
||||
this.setState({loading: false, error: `${_("Cannot logout:")} ${JSON.stringify(e)}`});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -111,9 +112,9 @@ export default class Dashboard extends React.Component {
|
|||
|
||||
let balance = "";
|
||||
if (user){
|
||||
balance = (<span><strong>{ user.balance }</strong> credits</span>);
|
||||
balance = (<span><strong>{ user.balance }</strong> {_("credits")}</span>);
|
||||
if (user.plan !== null){
|
||||
balance = (<span><strong>Unlimited</strong></span>);
|
||||
balance = (<span><strong>{_("Unlimited")}</strong></span>);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,15 +127,15 @@ export default class Dashboard extends React.Component {
|
|||
{ user ?
|
||||
<div>
|
||||
<div className="balance">
|
||||
Balance: { balance }
|
||||
<button className="btn btn-primary btn-sm" onClick={this.handleBuyCredits}><i className="fa fa-shopping-cart"></i> Buy Credits</button>
|
||||
<button className="btn btn-primary btn-sm" onClick={this.handleRefresh}><i className="fa fa-sync"></i> Refresh Balance</button>
|
||||
{_("Balance:")} { balance }
|
||||
<button className="btn btn-primary btn-sm" onClick={this.handleBuyCredits}><i className="fa fa-shopping-cart"></i> {_("Buy Credits")}</button>
|
||||
<button className="btn btn-primary btn-sm" onClick={this.handleRefresh}><i className="fa fa-sync"></i> {_("Refresh Balance")}</button>
|
||||
</div>
|
||||
|
||||
<h4>Hello, <a href="javascript:void(0)" onClick={this.handleOpenDashboard}>{ user.email }</a></h4>
|
||||
<h4>{_("Hello,")} <a href="javascript:void(0)" onClick={this.handleOpenDashboard}>{ user.email }</a></h4>
|
||||
|
||||
<div className="lightning-nodes">
|
||||
<h5>Synced Nodes</h5>
|
||||
<h5>{_("Synced Nodes")}</h5>
|
||||
{ syncingNodes ? <i className="fa fa-spin fa-sync"></i> :
|
||||
<div>
|
||||
<ul>
|
||||
|
@ -142,14 +143,14 @@ export default class Dashboard extends React.Component {
|
|||
<li key={n.id}><i className="fa fa-laptop"></i> <a href={`/processingnode/${n.id}/`}>{n.label}</a></li>
|
||||
)}
|
||||
</ul>
|
||||
<button className="btn btn-sm btn-default" onClick={this.handleSyncProcessingNode}><i className="fa fa-sync"></i> Resync</button>
|
||||
<button className="btn btn-sm btn-default" onClick={this.handleSyncProcessingNode}><i className="fa fa-sync"></i> {_("Resync")}</button>
|
||||
</div> }
|
||||
</div>
|
||||
|
||||
{nodes.length > 0 ?
|
||||
<div>
|
||||
<hr/>
|
||||
<i className="far fa-thumbs-up"></i> You are all set! When creating a new task from the <a href="/dashboard">Dashboard</a>, select <strong>{nodes[0].label}</strong> from the <strong>Processing Node</strong> drop-down instead of Auto.
|
||||
<hr/>
|
||||
<i className="far fa-thumbs-up"></i> <Trans params={{dashboard: `<a href="/dashboard">${_("Dashboard")}</a>`, name: `<strong>${nodes[0].label}</strong>`, node: `<strong>${_("Processing Node")}</strong>`}}>You are all set! When creating a new task from the %(dashboard)s, select %(name)s from the %(node)s drop-down instead of Auto.</Trans>
|
||||
</div> : ""}
|
||||
|
||||
<div className="buttons text-right">
|
||||
|
|
|
@ -3,6 +3,7 @@ import './Login.scss';
|
|||
import ErrorMessage from 'webodm/components/ErrorMessage';
|
||||
import PropTypes from 'prop-types';
|
||||
import $ from 'jquery';
|
||||
import { _ } from 'webodm/classes/gettext';
|
||||
|
||||
export default class Login extends React.Component {
|
||||
static defaultProps = {
|
||||
|
@ -52,11 +53,11 @@ export default class Login extends React.Component {
|
|||
}else if (json.message){
|
||||
this.setState({ loggingIn: false, error: json.message });
|
||||
}else{
|
||||
this.setState({ loggingIn: false, error: "Cannot login. Invalid response: " + JSON.stringify(json)});
|
||||
this.setState({ loggingIn: false, error: _("Cannot login. Invalid response:") + " " + JSON.stringify(json)});
|
||||
}
|
||||
})
|
||||
.fail(() => {
|
||||
this.setState({loggingIn: false, error: "Cannot login. Please make sure you are connected to the internet, or try again in an hour."});
|
||||
this.setState({loggingIn: false, error: _("Cannot login. Please make sure you are connected to the internet, or try again in an hour.")});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -86,27 +87,27 @@ export default class Login extends React.Component {
|
|||
<div className="form-group text-left">
|
||||
<input id="next" name="next" type="hidden" value="" />
|
||||
<p>
|
||||
<label htmlFor="email">E-mail Address</label>
|
||||
<label htmlFor="email">{_("E-mail Address")}</label>
|
||||
<input className="form-control" id="email" name="email" required=""
|
||||
type="text" value={this.state.email}
|
||||
onChange={this.handleEmailChange}
|
||||
onKeyPress={this.handleKeyPress} />
|
||||
</p>
|
||||
<p>
|
||||
<label htmlFor="password">Password</label>
|
||||
<label htmlFor="password">{_("Password")}</label>
|
||||
<input className="form-control" id="password" name="password" required=""
|
||||
type="password" value={this.state.password}
|
||||
onChange={this.handlePasswordChange}
|
||||
onKeyPress={this.handleKeyPress} />
|
||||
</p>
|
||||
<div style={{float: 'right'}} >
|
||||
<a href="https://webodm.net/register" target="_blank">Don't have an account?</a><br/>
|
||||
<a href="https://webodm.net/reset" target="_blank">Forgot password?</a>
|
||||
<a href="https://webodm.net/register" target="_blank">{_("Don't have an account?")}</a><br/>
|
||||
<a href="https://webodm.net/reset" target="_blank">{_("Forgot password?")}</a>
|
||||
</div>
|
||||
<p><button className="btn btn-primary" onClick={this.handleLogin} disabled={this.state.loggingIn}>
|
||||
{this.state.loggingIn ?
|
||||
<span><i className="fa fa-spin fa-circle-notch"></i></span> :
|
||||
<span><i className="fa fa-lock"></i> Login and Sync</span>}
|
||||
<span><i className="fa fa-lock"></i> {_("Login and Sync")}</span>}
|
||||
</button></p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,6 +2,8 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import Login from './Login';
|
||||
import Dashboard from './Dashboard';
|
||||
import { _ } from 'webodm/classes/gettext';
|
||||
import Trans from 'webodm/components/Trans';
|
||||
|
||||
export default class LightningPanel extends React.Component {
|
||||
static defaultProps = {
|
||||
|
@ -34,9 +36,10 @@ export default class LightningPanel extends React.Component {
|
|||
return (<div className="plugin-lightning">
|
||||
{ !apiKey ?
|
||||
<div>
|
||||
<h4><i className="fa fa-bolt"/> Lightning Network</h4>
|
||||
Lightning is a service that allows you to quickly process small and large datasets using high performance servers in the cloud.
|
||||
Below you can enter your <a href="https://webodm.net" target="_blank">webodm.net</a> credentials to sync your account and automatically setup a new processing node. If you don't have an account, you can <a href="https://webodm.net/register" target="_blank">register</a> for free.
|
||||
<h4><i className="fa fa-bolt"/> {_("Lightning Network")}</h4>
|
||||
{_("Lightning is a service that allows you to quickly process small and large datasets using high performance servers in the cloud.")}
|
||||
<Trans params={{ link: '<a href="https://webodm.net" target="_blank">webodm.net</a>', register: `<a href="https://webodm.net/register" target="_blank">${_("register")}</a>`}}>
|
||||
{_("Below you can enter your %(link)s credentials to sync your account and automatically setup a new processing node. If you don't have an account, you can %(register)s for free.")}</Trans>
|
||||
<Login onLogin={this.handleLogin} />
|
||||
</div> :
|
||||
<div>
|
||||
|
|
|
@ -14,6 +14,7 @@ from worker.tasks import execute_grass_script
|
|||
|
||||
from app.plugins.grass_engine import grass, GrassEngineException, cleanup_grass_context
|
||||
from geojson import Feature, Point, FeatureCollection
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class GeoJSONSerializer(serializers.Serializer):
|
||||
area = serializers.JSONField(help_text="Polygon contour defining the volume area to compute")
|
||||
|
@ -23,7 +24,7 @@ class TaskVolume(TaskView):
|
|||
def post(self, request, pk=None):
|
||||
task = self.get_and_check_task(request, pk)
|
||||
if task.dsm_extent is None:
|
||||
return Response({'error': 'No surface model available. From the Dashboard, select this task, press Edit, from the options make sure to check "dsm", then press Restart --> From DEM.'})
|
||||
return Response({'error': _('No surface model available. From the Dashboard, select this task, press Edit, from the options make sure to check "dsm", then press Restart --> From DEM.')})
|
||||
|
||||
serializer = GeoJSONSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||
import './MeasurePopup.scss';
|
||||
import Utils from 'webodm/classes/Utils';
|
||||
import Workers from 'webodm/classes/Workers';
|
||||
import { _, interpolate } from 'webodm/classes/gettext';
|
||||
|
||||
import $ from 'jquery';
|
||||
import L from 'leaflet';
|
||||
|
@ -101,7 +102,7 @@ export default class MeasurePopup extends React.Component {
|
|||
}else if (result.error){
|
||||
this.setState({error: result.error});
|
||||
}else{
|
||||
this.setState({error: "Invalid response: " + result});
|
||||
this.setState({error: interpolate(_("Invalid response: %(error)s"), { error: result})});
|
||||
}
|
||||
}).fail(error => {
|
||||
this.setState({error});
|
||||
|
@ -138,12 +139,12 @@ export default class MeasurePopup extends React.Component {
|
|||
const { volume, error } = this.state;
|
||||
|
||||
return (<div className="plugin-measure popup">
|
||||
<p>Area: {this.props.model.areaDisplay}</p>
|
||||
<p>Perimeter: {this.props.model.lengthDisplay}</p>
|
||||
{volume === null && !error && <p>Volume: <i>computing...</i> <i className="fa fa-cog fa-spin fa-fw" /></p>}
|
||||
{typeof volume === "number" && <p>Volume: {volume.toFixed("2")} Cubic Meters ({(volume * 35.3147).toFixed(2)} Cubic Feet)</p>}
|
||||
{error && <p>Volume: <span className={"error theme-background-failed " + (error.length > 200 ? 'long' : '')}>{error}</span></p>}
|
||||
<a href="#" onClick={this.exportMeasurement} className="export-measurements"><i className="fa fa-download"></i> Export to GeoJSON</a>
|
||||
<p>{_("Area:")} {this.props.model.areaDisplay}</p>
|
||||
<p>{_("Perimeter:")} {this.props.model.lengthDisplay}</p>
|
||||
{volume === null && !error && <p>{_("Volume:")} <i>{_("computing…")}</i> <i className="fa fa-cog fa-spin fa-fw" /></p>}
|
||||
{typeof volume === "number" && <p>{_("Volume:")} {volume.toFixed("2")} {_("Cubic Meters")} ({(volume * 35.3147).toFixed(2)} {_("Cubic Feet")})</p>}
|
||||
{error && <p>{_("Volume:")} <span className={"error theme-background-failed " + (error.length > 200 ? 'long' : '')}>{error}</span></p>}
|
||||
<a href="#" onClick={this.exportMeasurement} className="export-measurements"><i className="fa fa-download"></i> {_("Export to GeoJSON")}</a>
|
||||
</div>);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import Utils from 'webodm/classes/Utils';
|
|||
import ReactDOM from 'ReactDOM';
|
||||
import React from 'React';
|
||||
import $ from 'jquery';
|
||||
import { _ } from 'webodm/classes/gettext';
|
||||
|
||||
export default class App{
|
||||
constructor(map){
|
||||
|
@ -14,8 +15,8 @@ export default class App{
|
|||
|
||||
const measure = L.control.measure({
|
||||
labels:{
|
||||
measureDistancesAndAreas: 'Measure volume, area and length',
|
||||
areaMeasurement: 'Measurement'
|
||||
measureDistancesAndAreas: _('Measure volume, area and length'),
|
||||
areaMeasurement: _('Measurement')
|
||||
},
|
||||
primaryLengthUnit: 'meters',
|
||||
secondaryLengthUnit: 'feet',
|
||||
|
@ -23,7 +24,7 @@ export default class App{
|
|||
secondaryAreaUnit: 'acres'
|
||||
}).addTo(map);
|
||||
|
||||
const $btnExport = $("<br/><a href='#' class='js-start start'>Export Measurements</a>");
|
||||
const $btnExport = $(`<br/><a href='#' class='js-start start'>${_("Export Measurements")}</a>`);
|
||||
$btnExport.appendTo($(measure.$startPrompt).children("ul.tasks"));
|
||||
$btnExport.on('click', () => {
|
||||
const features = [];
|
||||
|
|
Ładowanie…
Reference in New Issue