mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-01-11 08:31:58 -06:00
Fine-tuning the import routine.
This commit is contained in:
parent
bbed5d0701
commit
c58eea6654
@ -54,7 +54,7 @@ class ImportController extends Controller
|
|||||||
if (!$this->jobInCorrectStep($job, 'complete')) {
|
if (!$this->jobInCorrectStep($job, 'complete')) {
|
||||||
return $this->redirectToCorrectStep($job);
|
return $this->redirectToCorrectStep($job);
|
||||||
}
|
}
|
||||||
$subTitle = trans('firefy.import_complete');
|
$subTitle = trans('firefly.import_complete');
|
||||||
$subTitleIcon = 'fa-star';
|
$subTitleIcon = 'fa-star';
|
||||||
|
|
||||||
return view('import.complete', compact('job', 'subTitle', 'subTitleIcon'));
|
return view('import.complete', compact('job', 'subTitle', 'subTitleIcon'));
|
||||||
@ -120,6 +120,19 @@ class ImportController extends Controller
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ImportJob $job
|
||||||
|
*
|
||||||
|
* @return View
|
||||||
|
*/
|
||||||
|
public function finished(ImportJob $job)
|
||||||
|
{
|
||||||
|
$subTitle = trans('firefly.import_finished');
|
||||||
|
$subTitleIcon = 'fa-star';
|
||||||
|
|
||||||
|
return view('import.finished', compact('job', 'subTitle', 'subTitleIcon'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is step 1. Upload a file.
|
* This is step 1. Upload a file.
|
||||||
*
|
*
|
||||||
@ -154,6 +167,7 @@ class ImportController extends Controller
|
|||||||
'started' => false,
|
'started' => false,
|
||||||
'completed' => false,
|
'completed' => false,
|
||||||
'running' => false,
|
'running' => false,
|
||||||
|
'errors' => $job->extended_status['errors'],
|
||||||
'percentage' => 0,
|
'percentage' => 0,
|
||||||
'steps' => $job->extended_status['total_steps'],
|
'steps' => $job->extended_status['total_steps'],
|
||||||
'stepsDone' => $job->extended_status['steps_done'],
|
'stepsDone' => $job->extended_status['steps_done'],
|
||||||
@ -290,7 +304,7 @@ class ImportController extends Controller
|
|||||||
if (!$this->jobInCorrectStep($job, 'status')) {
|
if (!$this->jobInCorrectStep($job, 'status')) {
|
||||||
return $this->redirectToCorrectStep($job);
|
return $this->redirectToCorrectStep($job);
|
||||||
}
|
}
|
||||||
$subTitle = trans('firefy.import_status');
|
$subTitle = trans('firefly.import_status');
|
||||||
$subTitleIcon = 'fa-star';
|
$subTitleIcon = 'fa-star';
|
||||||
|
|
||||||
return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
|
return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
|
||||||
@ -414,6 +428,8 @@ class ImportController extends Controller
|
|||||||
Log::debug('Will redirect to complete()');
|
Log::debug('Will redirect to complete()');
|
||||||
|
|
||||||
return redirect(route('import.complete', [$job->key]));
|
return redirect(route('import.complete', [$job->key]));
|
||||||
|
case 'import_complete':
|
||||||
|
return redirect(route('import.finished', [$job->key]));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FireflyException('Cannot redirect for job state ' . $job->status);
|
throw new FireflyException('Cannot redirect for job state ' . $job->status);
|
||||||
|
@ -234,8 +234,9 @@ Route::group(
|
|||||||
|
|
||||||
Route::get('/import/status/{importJob}', ['uses' => 'ImportController@status', 'as' => 'import.status']);
|
Route::get('/import/status/{importJob}', ['uses' => 'ImportController@status', 'as' => 'import.status']);
|
||||||
Route::get('/import/json/{importJob}', ['uses' => 'ImportController@json', 'as' => 'import.json']);
|
Route::get('/import/json/{importJob}', ['uses' => 'ImportController@json', 'as' => 'import.json']);
|
||||||
Route::post('/import/start/{importJob}', ['uses' => 'ImportController@start', 'as' => 'import.start']);
|
|
||||||
|
|
||||||
|
Route::post('/import/start/{importJob}', ['uses' => 'ImportController@start', 'as' => 'import.start']);
|
||||||
|
Route::get('/import/finished/{importJob}', ['uses' => 'ImportController@finished', 'as' => 'import.finished']);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Help Controller
|
* Help Controller
|
||||||
|
@ -220,8 +220,13 @@ class ImportStorage
|
|||||||
Log::warning(sprintf('Cannot import row %d, because the entry is not valid.', $index));
|
Log::warning(sprintf('Cannot import row %d, because the entry is not valid.', $index));
|
||||||
$result = new ImportResult();
|
$result = new ImportResult();
|
||||||
$result->failed();
|
$result->failed();
|
||||||
$errors = join(', ', $entry->errors->all());
|
$errors = join(', ', $entry->errors->all());
|
||||||
$result->appendError(sprintf('Row #%d: ' . $errors, $index));
|
$errorText = sprintf('Row #%d: ' . $errors, $index);
|
||||||
|
$result->appendError($errorText);
|
||||||
|
$extendedStatus = $this->job->extended_status;
|
||||||
|
$extendedStatus['errors'][] = $errorText;
|
||||||
|
$this->job->extended_status = $extendedStatus;
|
||||||
|
$this->job->save();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface
|
|||||||
$importJob->file_type = $fileType;
|
$importJob->file_type = $fileType;
|
||||||
$importJob->key = Str::random(12);
|
$importJob->key = Str::random(12);
|
||||||
$importJob->status = 'import_status_never_started';
|
$importJob->status = 'import_status_never_started';
|
||||||
$importJob->extended_status = ['total_steps' => 0, 'steps_done' => 0,];
|
$importJob->extended_status = ['total_steps' => 0, 'steps_done' => 0, 'errors' => [], 'import_count' => 0];
|
||||||
$importJob->save();
|
$importJob->save();
|
||||||
|
|
||||||
// breaks the loop:
|
// breaks the loop:
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
|
|
||||||
|
|
||||||
var startedImport = false;
|
var startedImport = false;
|
||||||
|
var startInterval = 2000;
|
||||||
var interval = 500;
|
var interval = 500;
|
||||||
$(function () {
|
$(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// check status, every 500 ms.
|
// check status, every 500 ms.
|
||||||
setTimeout(checkImportStatus, 500);
|
setTimeout(checkImportStatus, startInterval);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -24,54 +25,85 @@ function checkImportStatus() {
|
|||||||
$.getJSON(jobImportUrl).success(reportOnJobImport).fail(failedJobImport);
|
$.getJSON(jobImportUrl).success(reportOnJobImport).fail(failedJobImport);
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportOnJobImport(data) {
|
function importComplete(data) {
|
||||||
"use strict";
|
"use strict";
|
||||||
console.log('Now in reportOnJobImport');
|
var bar = $('#import-status-bar');
|
||||||
|
bar.removeClass('active');
|
||||||
// update bar if it's a percentage or not:
|
// TODO show more completion info.
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBar(data) {
|
||||||
|
"use strict";
|
||||||
var bar = $('#import-status-bar');
|
var bar = $('#import-status-bar');
|
||||||
if (data.showPercentage) {
|
if (data.showPercentage) {
|
||||||
console.log('Has percentage.');
|
|
||||||
bar.addClass('progress-bar-success').removeClass('progress-bar-info');
|
bar.addClass('progress-bar-success').removeClass('progress-bar-info');
|
||||||
bar.attr('aria-valuenow', data.percentage);
|
bar.attr('aria-valuenow', data.percentage);
|
||||||
bar.css('width', data.percentage + '%');
|
bar.css('width', data.percentage + '%');
|
||||||
$('#import-status-bar').text(data.stepsDone + '/' + data.steps);
|
$('#import-status-bar').text(data.stepsDone + '/' + data.steps);
|
||||||
|
|
||||||
|
|
||||||
if (data.percentage >= 100) {
|
if (data.percentage >= 100) {
|
||||||
console.log('Now import complete!');
|
importComplete(data);
|
||||||
bar.removeClass('active');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// dont show percentage:
|
||||||
|
$('#import-status-more-info').text('');
|
||||||
|
bar.removeClass('progress-bar-success').addClass('progress-bar-info');
|
||||||
|
bar.attr('aria-valuenow', 100);
|
||||||
|
bar.css('width', '100%');
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
function reportErrors(data) {
|
||||||
$('#import-status-more-info').text('');
|
"use strict";
|
||||||
console.log('Has no percentage.');
|
if (data.errors.length == 1) {
|
||||||
bar.removeClass('progress-bar-success').addClass('progress-bar-info');
|
$('#import-status-error-intro').text('An error has occured during the import. The import can continue, however.');
|
||||||
bar.attr('aria-valuenow', 100);
|
}
|
||||||
bar.css('width', '100%');
|
if (data.errors.length > 1) {
|
||||||
|
$('#import-status-error-intro').text('Errors have occured during the import. The import can continue, however.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the message:
|
// fill the list:
|
||||||
|
$('#import-status-error-list').empty();
|
||||||
|
for (var i = 0; i < data.errors.length; i++) {
|
||||||
|
var item = $('<li>').text(data.errors[i]);
|
||||||
|
$('#import-status-error-list').append(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportStatus(data) {
|
||||||
|
"use strict";
|
||||||
$('#import-status-txt').removeClass('text-danger').text(data.statusText);
|
$('#import-status-txt').removeClass('text-danger').text(data.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
function kickStartJob() {
|
||||||
|
"use strict";
|
||||||
|
$.post(jobStartUrl, {_token: token});
|
||||||
|
startedTheImport();
|
||||||
|
startedImport = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportOnJobImport(data) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
updateBar(data);
|
||||||
|
reportErrors(data);
|
||||||
|
reportStatus(data);
|
||||||
|
|
||||||
// if the job has not actually started, do so now:
|
// if the job has not actually started, do so now:
|
||||||
if (!data.started && !startedImport) {
|
if (!data.started && !startedImport) {
|
||||||
console.log('Will now start job.');
|
kickStartJob();
|
||||||
$.post(jobStartUrl, {_token: token});
|
return;
|
||||||
startedTheImport();
|
|
||||||
startedImport = true;
|
|
||||||
} else {
|
|
||||||
// trigger another check.
|
|
||||||
setTimeout(checkImportStatus, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trigger another check.
|
||||||
|
setTimeout(checkImportStatus, interval);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function startedTheImport() {
|
function startedTheImport() {
|
||||||
"use strict";
|
"use strict";
|
||||||
console.log('Started the import. Now starting over again.');
|
setTimeout(checkImportStatus, interval);
|
||||||
setTimeout(checkImportStatus, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function failedJobImport(jqxhr, textStatus, error) {
|
function failedJobImport(jqxhr, textStatus, error) {
|
||||||
|
@ -781,5 +781,5 @@ return [
|
|||||||
'import_file_help' => 'Select your file',
|
'import_file_help' => 'Select your file',
|
||||||
'import_status_settings_complete' => 'The import is ready to start.',
|
'import_status_settings_complete' => 'The import is ready to start.',
|
||||||
'import_status_import_complete' => 'The import has completed.',
|
'import_status_import_complete' => 'The import has completed.',
|
||||||
'import_status_import_running' => 'The import is currently running. Please be patient. An apparent lack of progress may be a trick of the light.',
|
'import_status_import_running' => 'The import is currently running. Please be patient.',
|
||||||
];
|
];
|
||||||
|
25
resources/views/import/finished.twig
Normal file
25
resources/views/import/finished.twig
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{% extends "./layout/default.twig" %}
|
||||||
|
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{{ Breadcrumbs.renderIfExists }}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||||
|
<div class="box box-default">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'import_finished'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
|
||||||
|
This import has beeen done. Link to tag or set of transactions.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block scripts %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block styles %}
|
||||||
|
{% endblock %}
|
@ -11,9 +11,6 @@
|
|||||||
<h3 class="box-title">{{ 'import_status'|_ }}</h3>
|
<h3 class="box-title">{{ 'import_status'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<p>
|
|
||||||
{{ 'import_status_text'|_ }}
|
|
||||||
</p>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-lg-6 col-lg-offset-3">
|
<div class="col-lg-6 col-lg-offset-3">
|
||||||
@ -23,8 +20,10 @@
|
|||||||
aria-valuemax="100" style="width: 100%">
|
aria-valuemax="100" style="width: 100%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p id="import-status-txt"></p>
|
<p id="import-status-txt">{{ 'import_status_settings_complete'|_ }}</p>
|
||||||
<p id="import-status-more-info"></p>
|
<p id="import-status-more-info"></p>
|
||||||
|
<p id="import-status-error-intro"></p>
|
||||||
|
<ul id="import-status-error-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -98,7 +98,9 @@
|
|||||||
"status": "settings_complete",
|
"status": "settings_complete",
|
||||||
"extended_status": {
|
"extended_status": {
|
||||||
"steps_done": 0,
|
"steps_done": 0,
|
||||||
"total_steps": 0
|
"total_steps": 0,
|
||||||
|
"errors": [],
|
||||||
|
"import_count": 0
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"has-headers": false,
|
"has-headers": false,
|
||||||
|
Loading…
Reference in New Issue
Block a user