Fine-tuning the import routine.

This commit is contained in:
James Cole 2016-08-13 23:28:01 +02:00
parent bbed5d0701
commit c58eea6654
9 changed files with 117 additions and 37 deletions

View File

@ -54,7 +54,7 @@ class ImportController extends Controller
if (!$this->jobInCorrectStep($job, 'complete')) {
return $this->redirectToCorrectStep($job);
}
$subTitle = trans('firefy.import_complete');
$subTitle = trans('firefly.import_complete');
$subTitleIcon = 'fa-star';
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.
*
@ -154,6 +167,7 @@ class ImportController extends Controller
'started' => false,
'completed' => false,
'running' => false,
'errors' => $job->extended_status['errors'],
'percentage' => 0,
'steps' => $job->extended_status['total_steps'],
'stepsDone' => $job->extended_status['steps_done'],
@ -290,7 +304,7 @@ class ImportController extends Controller
if (!$this->jobInCorrectStep($job, 'status')) {
return $this->redirectToCorrectStep($job);
}
$subTitle = trans('firefy.import_status');
$subTitle = trans('firefly.import_status');
$subTitleIcon = 'fa-star';
return view('import.status', compact('job', 'subTitle', 'subTitleIcon'));
@ -414,6 +428,8 @@ class ImportController extends Controller
Log::debug('Will redirect to complete()');
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);

View File

@ -234,8 +234,9 @@ Route::group(
Route::get('/import/status/{importJob}', ['uses' => 'ImportController@status', 'as' => 'import.status']);
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

View File

@ -220,8 +220,13 @@ class ImportStorage
Log::warning(sprintf('Cannot import row %d, because the entry is not valid.', $index));
$result = new ImportResult();
$result->failed();
$errors = join(', ', $entry->errors->all());
$result->appendError(sprintf('Row #%d: ' . $errors, $index));
$errors = join(', ', $entry->errors->all());
$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;
}

View File

@ -52,7 +52,7 @@ class ImportJobRepository implements ImportJobRepositoryInterface
$importJob->file_type = $fileType;
$importJob->key = Str::random(12);
$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();
// breaks the loop:

View File

@ -9,12 +9,13 @@
var startedImport = false;
var startInterval = 2000;
var interval = 500;
$(function () {
"use strict";
// check status, every 500 ms.
setTimeout(checkImportStatus, 500);
setTimeout(checkImportStatus, startInterval);
});
@ -24,54 +25,85 @@ function checkImportStatus() {
$.getJSON(jobImportUrl).success(reportOnJobImport).fail(failedJobImport);
}
function reportOnJobImport(data) {
function importComplete(data) {
"use strict";
console.log('Now in reportOnJobImport');
// update bar if it's a percentage or not:
var bar = $('#import-status-bar');
bar.removeClass('active');
// TODO show more completion info.
}
function updateBar(data) {
"use strict";
var bar = $('#import-status-bar');
if (data.showPercentage) {
console.log('Has percentage.');
bar.addClass('progress-bar-success').removeClass('progress-bar-info');
bar.attr('aria-valuenow', data.percentage);
bar.css('width', data.percentage + '%');
$('#import-status-bar').text(data.stepsDone + '/' + data.steps);
if (data.percentage >= 100) {
console.log('Now import complete!');
bar.removeClass('active');
importComplete(data);
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 {
$('#import-status-more-info').text('');
console.log('Has no percentage.');
bar.removeClass('progress-bar-success').addClass('progress-bar-info');
bar.attr('aria-valuenow', 100);
bar.css('width', '100%');
function reportErrors(data) {
"use strict";
if (data.errors.length == 1) {
$('#import-status-error-intro').text('An error has occured during the import. The import can continue, however.');
}
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);
}
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 (!data.started && !startedImport) {
console.log('Will now start job.');
$.post(jobStartUrl, {_token: token});
startedTheImport();
startedImport = true;
} else {
// trigger another check.
setTimeout(checkImportStatus, 500);
kickStartJob();
return;
}
// trigger another check.
setTimeout(checkImportStatus, interval);
}
function startedTheImport() {
"use strict";
console.log('Started the import. Now starting over again.');
setTimeout(checkImportStatus, 500);
setTimeout(checkImportStatus, interval);
}
function failedJobImport(jqxhr, textStatus, error) {

View File

@ -781,5 +781,5 @@ return [
'import_file_help' => 'Select your file',
'import_status_settings_complete' => 'The import is ready to start.',
'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.',
];

View 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 %}

View File

@ -11,9 +11,6 @@
<h3 class="box-title">{{ 'import_status'|_ }}</h3>
</div>
<div class="box-body">
<p>
{{ 'import_status_text'|_ }}
</p>
<div class="row">
<div class="col-lg-6 col-lg-offset-3">
@ -23,8 +20,10 @@
aria-valuemax="100" style="width: 100%">
</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-error-intro"></p>
<ul id="import-status-error-list"></ul>
</div>
</div>

View File

@ -98,7 +98,9 @@
"status": "settings_complete",
"extended_status": {
"steps_done": 0,
"total_steps": 0
"total_steps": 0,
"errors": [],
"import_count": 0
},
"configuration": {
"has-headers": false,