diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php index ba58c4d113..9b40c428c9 100644 --- a/app/Http/Controllers/ImportController.php +++ b/app/Http/Controllers/ImportController.php @@ -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); diff --git a/app/Http/routes.php b/app/Http/routes.php index a29f331a7f..0fe44e5fec 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -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 diff --git a/app/Import/ImportStorage.php b/app/Import/ImportStorage.php index 5a2f37a03e..db06eb5251 100644 --- a/app/Import/ImportStorage.php +++ b/app/Import/ImportStorage.php @@ -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; } diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php index ae96b61115..0064cca67e 100644 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ b/app/Repositories/ImportJob/ImportJobRepository.php @@ -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: diff --git a/public/js/ff/import/status.js b/public/js/ff/import/status.js index fa7ce2d9b7..a312dd6b8c 100644 --- a/public/js/ff/import/status.js +++ b/public/js/ff/import/status.js @@ -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 = $('
  • ').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) { diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 40d60e76ef..d34d230e31 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -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.', ]; diff --git a/resources/views/import/finished.twig b/resources/views/import/finished.twig new file mode 100644 index 0000000000..4a6f7e9903 --- /dev/null +++ b/resources/views/import/finished.twig @@ -0,0 +1,25 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists }} +{% endblock %} +{% block content %} +
    +
    +
    +
    +

    {{ 'import_finished'|_ }}

    +
    +
    + + This import has beeen done. Link to tag or set of transactions. + +
    +
    +
    +
    +{% endblock %} +{% block scripts %} +{% endblock %} +{% block styles %} +{% endblock %} diff --git a/resources/views/import/status.twig b/resources/views/import/status.twig index 37510ca6f1..9a6bc4888b 100644 --- a/resources/views/import/status.twig +++ b/resources/views/import/status.twig @@ -11,9 +11,6 @@

    {{ 'import_status'|_ }}

    -

    - {{ 'import_status_text'|_ }} -

    @@ -23,8 +20,10 @@ aria-valuemax="100" style="width: 100%">
    -

    +

    {{ 'import_status_settings_complete'|_ }}

    +

    +
    diff --git a/storage/database/seed.import-test.json b/storage/database/seed.import-test.json index 1bff69943c..f6f1ec7f84 100644 --- a/storage/database/seed.import-test.json +++ b/storage/database/seed.import-test.json @@ -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,