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 ResizeModes from 'webodm/classes/ResizeModes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { _ } from 'webodm/classes/gettext';
|
||||||
|
|
||||||
export default class CostEstimateItem extends React.Component {
|
export default class CostEstimateItem extends React.Component {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -99,10 +100,10 @@ export default class CostEstimateItem extends React.Component {
|
||||||
if (json.credits_estimate === 0) json.credits_estimate += " (Free)";
|
if (json.credits_estimate === 0) json.credits_estimate += " (Free)";
|
||||||
this.setState({credits: json.credits_estimate})
|
this.setState({credits: json.credits_estimate})
|
||||||
}else{
|
}else{
|
||||||
this.setState({credits: "Cannot retrieve estimate. Try again later."});
|
this.setState({credits: _("Cannot retrieve estimate. Try again later.")});
|
||||||
}
|
}
|
||||||
}).fail(e => {
|
}).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(() => {
|
}).always(() => {
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
this.estimateRequest = null;
|
this.estimateRequest = null;
|
||||||
|
@ -135,7 +136,7 @@ export default class CostEstimateItem extends React.Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"lightning-cost-estimate-item " + (show ? "" : "hide")}>
|
<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">
|
<div className="col-sm-10 num-credits">
|
||||||
{loading ?
|
{loading ?
|
||||||
<i className="fa fa-circle-notch fa-spin"></i> :
|
<i className="fa fa-circle-notch fa-spin"></i> :
|
||||||
|
|
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import './Dashboard.scss';
|
import './Dashboard.scss';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { _ } from 'webodm/classes/gettext';
|
import { _ } from 'webodm/classes/gettext';
|
||||||
|
import Trans from 'webodm/components/Trans';
|
||||||
|
|
||||||
export default class Dashboard extends React.Component {
|
export default class Dashboard extends React.Component {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -44,11 +45,11 @@ export default class Dashboard extends React.Component {
|
||||||
}else if (json.message === "Unauthorized"){
|
}else if (json.message === "Unauthorized"){
|
||||||
this.props.onLogout();
|
this.props.onLogout();
|
||||||
}else{
|
}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(() => {
|
.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 => {
|
.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(() => {
|
.always(() => {
|
||||||
this.setState({syncingNodes: false});
|
this.setState({syncingNodes: false});
|
||||||
|
@ -79,18 +80,18 @@ export default class Dashboard extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handeLogout = () => {
|
handeLogout = () => {
|
||||||
this.setState({loading: true, loadingMessage: "Logging out..."});
|
this.setState({loading: true, loadingMessage: _('Logging out…')});
|
||||||
|
|
||||||
$.post("save_api_key", {
|
$.post("save_api_key", {
|
||||||
api_key: ""
|
api_key: ""
|
||||||
}).done(json => {
|
}).done(json => {
|
||||||
if (!json.success){
|
if (!json.success){
|
||||||
this.setState({error: `Cannot logout: ${JSON.stringify(json)}`});
|
this.setState({error: `${_("Cannot logout:")} ${JSON.stringify(json)}`});
|
||||||
}
|
}
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
this.props.onLogout();
|
this.props.onLogout();
|
||||||
}).fail(e => {
|
}).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 = "";
|
let balance = "";
|
||||||
if (user){
|
if (user){
|
||||||
balance = (<span><strong>{ user.balance }</strong> credits</span>);
|
balance = (<span><strong>{ user.balance }</strong> {_("credits")}</span>);
|
||||||
if (user.plan !== null){
|
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 ?
|
{ user ?
|
||||||
<div>
|
<div>
|
||||||
<div className="balance">
|
<div className="balance">
|
||||||
Balance: { 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.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>
|
<button className="btn btn-primary btn-sm" onClick={this.handleRefresh}><i className="fa fa-sync"></i> {_("Refresh Balance")}</button>
|
||||||
</div>
|
</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">
|
<div className="lightning-nodes">
|
||||||
<h5>Synced Nodes</h5>
|
<h5>{_("Synced Nodes")}</h5>
|
||||||
{ syncingNodes ? <i className="fa fa-spin fa-sync"></i> :
|
{ syncingNodes ? <i className="fa fa-spin fa-sync"></i> :
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
<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>
|
<li key={n.id}><i className="fa fa-laptop"></i> <a href={`/processingnode/${n.id}/`}>{n.label}</a></li>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</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> }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{nodes.length > 0 ?
|
{nodes.length > 0 ?
|
||||||
<div>
|
<div>
|
||||||
<hr/>
|
<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.
|
<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> : ""}
|
||||||
|
|
||||||
<div className="buttons text-right">
|
<div className="buttons text-right">
|
||||||
|
|
|
@ -3,6 +3,7 @@ import './Login.scss';
|
||||||
import ErrorMessage from 'webodm/components/ErrorMessage';
|
import ErrorMessage from 'webodm/components/ErrorMessage';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { _ } from 'webodm/classes/gettext';
|
||||||
|
|
||||||
export default class Login extends React.Component {
|
export default class Login extends React.Component {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -52,11 +53,11 @@ export default class Login extends React.Component {
|
||||||
}else if (json.message){
|
}else if (json.message){
|
||||||
this.setState({ loggingIn: false, error: json.message });
|
this.setState({ loggingIn: false, error: json.message });
|
||||||
}else{
|
}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(() => {
|
.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">
|
<div className="form-group text-left">
|
||||||
<input id="next" name="next" type="hidden" value="" />
|
<input id="next" name="next" type="hidden" value="" />
|
||||||
<p>
|
<p>
|
||||||
<label htmlFor="email">E-mail Address</label>
|
<label htmlFor="email">{_("E-mail Address")}</label>
|
||||||
<input className="form-control" id="email" name="email" required=""
|
<input className="form-control" id="email" name="email" required=""
|
||||||
type="text" value={this.state.email}
|
type="text" value={this.state.email}
|
||||||
onChange={this.handleEmailChange}
|
onChange={this.handleEmailChange}
|
||||||
onKeyPress={this.handleKeyPress} />
|
onKeyPress={this.handleKeyPress} />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label htmlFor="password">Password</label>
|
<label htmlFor="password">{_("Password")}</label>
|
||||||
<input className="form-control" id="password" name="password" required=""
|
<input className="form-control" id="password" name="password" required=""
|
||||||
type="password" value={this.state.password}
|
type="password" value={this.state.password}
|
||||||
onChange={this.handlePasswordChange}
|
onChange={this.handlePasswordChange}
|
||||||
onKeyPress={this.handleKeyPress} />
|
onKeyPress={this.handleKeyPress} />
|
||||||
</p>
|
</p>
|
||||||
<div style={{float: 'right'}} >
|
<div style={{float: 'right'}} >
|
||||||
<a href="https://webodm.net/register" target="_blank">Don't have an account?</a><br/>
|
<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/reset" target="_blank">{_("Forgot password?")}</a>
|
||||||
</div>
|
</div>
|
||||||
<p><button className="btn btn-primary" onClick={this.handleLogin} disabled={this.state.loggingIn}>
|
<p><button className="btn btn-primary" onClick={this.handleLogin} disabled={this.state.loggingIn}>
|
||||||
{this.state.loggingIn ?
|
{this.state.loggingIn ?
|
||||||
<span><i className="fa fa-spin fa-circle-notch"></i></span> :
|
<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>
|
</button></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,8 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Login from './Login';
|
import Login from './Login';
|
||||||
import Dashboard from './Dashboard';
|
import Dashboard from './Dashboard';
|
||||||
|
import { _ } from 'webodm/classes/gettext';
|
||||||
|
import Trans from 'webodm/components/Trans';
|
||||||
|
|
||||||
export default class LightningPanel extends React.Component {
|
export default class LightningPanel extends React.Component {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -34,9 +36,10 @@ export default class LightningPanel extends React.Component {
|
||||||
return (<div className="plugin-lightning">
|
return (<div className="plugin-lightning">
|
||||||
{ !apiKey ?
|
{ !apiKey ?
|
||||||
<div>
|
<div>
|
||||||
<h4><i className="fa fa-bolt"/> Lightning Network</h4>
|
<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.
|
{_("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.
|
<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} />
|
<Login onLogin={this.handleLogin} />
|
||||||
</div> :
|
</div> :
|
||||||
<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 app.plugins.grass_engine import grass, GrassEngineException, cleanup_grass_context
|
||||||
from geojson import Feature, Point, FeatureCollection
|
from geojson import Feature, Point, FeatureCollection
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
class GeoJSONSerializer(serializers.Serializer):
|
class GeoJSONSerializer(serializers.Serializer):
|
||||||
area = serializers.JSONField(help_text="Polygon contour defining the volume area to compute")
|
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):
|
def post(self, request, pk=None):
|
||||||
task = self.get_and_check_task(request, pk)
|
task = self.get_and_check_task(request, pk)
|
||||||
if task.dsm_extent is None:
|
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 = GeoJSONSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||||
import './MeasurePopup.scss';
|
import './MeasurePopup.scss';
|
||||||
import Utils from 'webodm/classes/Utils';
|
import Utils from 'webodm/classes/Utils';
|
||||||
import Workers from 'webodm/classes/Workers';
|
import Workers from 'webodm/classes/Workers';
|
||||||
|
import { _, interpolate } from 'webodm/classes/gettext';
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import L from 'leaflet';
|
import L from 'leaflet';
|
||||||
|
@ -101,7 +102,7 @@ export default class MeasurePopup extends React.Component {
|
||||||
}else if (result.error){
|
}else if (result.error){
|
||||||
this.setState({error: result.error});
|
this.setState({error: result.error});
|
||||||
}else{
|
}else{
|
||||||
this.setState({error: "Invalid response: " + result});
|
this.setState({error: interpolate(_("Invalid response: %(error)s"), { error: result})});
|
||||||
}
|
}
|
||||||
}).fail(error => {
|
}).fail(error => {
|
||||||
this.setState({error});
|
this.setState({error});
|
||||||
|
@ -138,12 +139,12 @@ export default class MeasurePopup extends React.Component {
|
||||||
const { volume, error } = this.state;
|
const { volume, error } = this.state;
|
||||||
|
|
||||||
return (<div className="plugin-measure popup">
|
return (<div className="plugin-measure popup">
|
||||||
<p>Area: {this.props.model.areaDisplay}</p>
|
<p>{_("Area:")} {this.props.model.areaDisplay}</p>
|
||||||
<p>Perimeter: {this.props.model.lengthDisplay}</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>}
|
{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>}
|
{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>}
|
{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>
|
<a href="#" onClick={this.exportMeasurement} className="export-measurements"><i className="fa fa-download"></i> {_("Export to GeoJSON")}</a>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import Utils from 'webodm/classes/Utils';
|
||||||
import ReactDOM from 'ReactDOM';
|
import ReactDOM from 'ReactDOM';
|
||||||
import React from 'React';
|
import React from 'React';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { _ } from 'webodm/classes/gettext';
|
||||||
|
|
||||||
export default class App{
|
export default class App{
|
||||||
constructor(map){
|
constructor(map){
|
||||||
|
@ -14,8 +15,8 @@ export default class App{
|
||||||
|
|
||||||
const measure = L.control.measure({
|
const measure = L.control.measure({
|
||||||
labels:{
|
labels:{
|
||||||
measureDistancesAndAreas: 'Measure volume, area and length',
|
measureDistancesAndAreas: _('Measure volume, area and length'),
|
||||||
areaMeasurement: 'Measurement'
|
areaMeasurement: _('Measurement')
|
||||||
},
|
},
|
||||||
primaryLengthUnit: 'meters',
|
primaryLengthUnit: 'meters',
|
||||||
secondaryLengthUnit: 'feet',
|
secondaryLengthUnit: 'feet',
|
||||||
|
@ -23,7 +24,7 @@ export default class App{
|
||||||
secondaryAreaUnit: 'acres'
|
secondaryAreaUnit: 'acres'
|
||||||
}).addTo(map);
|
}).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.appendTo($(measure.$startPrompt).children("ul.tasks"));
|
||||||
$btnExport.on('click', () => {
|
$btnExport.on('click', () => {
|
||||||
const features = [];
|
const features = [];
|
||||||
|
|
Ładowanie…
Reference in New Issue