Merge pull request #5156 from betagouv/dev
This commit is contained in:
commit
5317e219a4
8 changed files with 1120 additions and 1296 deletions
|
@ -1,6 +1,9 @@
|
||||||
import Uploader from '../../shared/activestorage/uploader';
|
import Uploader from '../../shared/activestorage/uploader';
|
||||||
import { show, hide, toggle } from '@utils';
|
import { show, hide, toggle } from '@utils';
|
||||||
import { FAILURE_CONNECTIVITY } from '../../shared/activestorage/file-upload-error';
|
import {
|
||||||
|
ERROR_CODE_READ,
|
||||||
|
FAILURE_CONNECTIVITY
|
||||||
|
} from '../../shared/activestorage/file-upload-error';
|
||||||
|
|
||||||
// Given a file input in a champ with a selected file, upload a file,
|
// Given a file input in a champ with a selected file, upload a file,
|
||||||
// then attach it to the dossier.
|
// then attach it to the dossier.
|
||||||
|
@ -68,6 +71,12 @@ export default class AutoUploadController {
|
||||||
description: 'Vérifiez votre connexion à Internet, puis ré-essayez.',
|
description: 'Vérifiez votre connexion à Internet, puis ré-essayez.',
|
||||||
retry: true
|
retry: true
|
||||||
};
|
};
|
||||||
|
} else if (error.code == ERROR_CODE_READ) {
|
||||||
|
return {
|
||||||
|
title: 'Nous n’arrivons pas à lire ce fichier sur votre appareil.',
|
||||||
|
description: 'Essayez à nouveau, ou sélectionnez un autre fichier.',
|
||||||
|
retry: false
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
title: 'Le fichier n’a pas pu être envoyé.',
|
title: 'Le fichier n’a pas pu être envoyé.',
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import Rails from '@rails/ujs';
|
import Rails from '@rails/ujs';
|
||||||
import AutoUploadController from './auto-upload-controller.js';
|
import AutoUploadController from './auto-upload-controller.js';
|
||||||
import { fire } from '@utils';
|
import {
|
||||||
import { FAILURE_CONNECTIVITY } from '../../shared/activestorage/file-upload-error';
|
FAILURE_CLIENT,
|
||||||
|
ERROR_CODE_READ
|
||||||
//
|
} from '../../shared/activestorage/file-upload-error';
|
||||||
// DEBUG
|
|
||||||
//
|
|
||||||
const originalImpl = FileReader.prototype.addEventListener;
|
|
||||||
|
|
||||||
// Manage multiple concurrent uploads.
|
// Manage multiple concurrent uploads.
|
||||||
//
|
//
|
||||||
|
@ -24,10 +21,11 @@ export default class AutoUploadsControllers {
|
||||||
try {
|
try {
|
||||||
let controller = new AutoUploadController(input, file);
|
let controller = new AutoUploadController(input, file);
|
||||||
await controller.start();
|
await controller.start();
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
// Report errors to Sentry (except connectivity issues)
|
// Report unexpected client errors to Sentry.
|
||||||
if (error.failureReason != FAILURE_CONNECTIVITY) {
|
// (But ignore usual client errors, or errors we can monitor better on the server side.)
|
||||||
throw error;
|
if (err.failureReason == FAILURE_CLIENT && err.code != ERROR_CODE_READ) {
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this._decrementInFlightUploads(form);
|
this._decrementInFlightUploads(form);
|
||||||
|
@ -42,25 +40,6 @@ export default class AutoUploadsControllers {
|
||||||
.querySelectorAll('button[type=submit]')
|
.querySelectorAll('button[type=submit]')
|
||||||
.forEach((submitButton) => Rails.disableElement(submitButton));
|
.forEach((submitButton) => Rails.disableElement(submitButton));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// DEBUG: hook into FileReader onload event
|
|
||||||
//
|
|
||||||
if (FileReader.prototype.addEventListener === originalImpl) {
|
|
||||||
FileReader.prototype.addEventListener = function () {
|
|
||||||
// When DirectUploads attempts to add an event listener for "error",
|
|
||||||
// also insert a custom event listener of our that will report errors to Sentry.
|
|
||||||
if (arguments[0] == 'error') {
|
|
||||||
let handler = (event) => {
|
|
||||||
let message = `FileReader ${event.target.error.name}: ${event.target.error.message}`;
|
|
||||||
fire(document, 'sentry:capture-exception', new Error(message));
|
|
||||||
};
|
|
||||||
originalImpl.apply(this, ['error', handler]);
|
|
||||||
}
|
|
||||||
// Add the originally requested event listener
|
|
||||||
return originalImpl.apply(this, arguments);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_decrementInFlightUploads(form) {
|
_decrementInFlightUploads(form) {
|
||||||
|
@ -73,12 +52,5 @@ export default class AutoUploadsControllers {
|
||||||
.querySelectorAll('button[type=submit]')
|
.querySelectorAll('button[type=submit]')
|
||||||
.forEach((submitButton) => Rails.enableElement(submitButton));
|
.forEach((submitButton) => Rails.enableElement(submitButton));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// DEBUG: remove the FileReader hook we set before.
|
|
||||||
//
|
|
||||||
if (this.inFlightUploadsCount == 0) {
|
|
||||||
FileReader.prototype.addEventListener = originalImpl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ ActiveStorage.start();
|
||||||
window.DS = window.DS || DS;
|
window.DS = window.DS || DS;
|
||||||
|
|
||||||
// Now that Turbolinks is globally exposed,configure ReactRailsUJS
|
// Now that Turbolinks is globally exposed,configure ReactRailsUJS
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef, react-hooks/rules-of-hooks
|
||||||
ReactRailsUJS.useContext(require.context('loaders', true));
|
ReactRailsUJS.useContext(require.context('loaders', true));
|
||||||
// Remove previous event handlers and add new ones:
|
// Remove previous event handlers and add new ones:
|
||||||
ReactRailsUJS.detectEvents();
|
ReactRailsUJS.detectEvents();
|
||||||
|
|
|
@ -36,6 +36,10 @@ class Champs::PieceJustificativeChamp < Champ
|
||||||
mandatory? && !piece_justificative_file.attached?
|
mandatory? && !piece_justificative_file.attached?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def for_export
|
||||||
|
piece_justificative_file.filename.to_s if piece_justificative_file.attached?
|
||||||
|
end
|
||||||
|
|
||||||
def for_api
|
def for_api
|
||||||
if piece_justificative_file.attached? && (piece_justificative_file.virus_scanner.safe? || piece_justificative_file.virus_scanner.pending?)
|
if piece_justificative_file.attached? && (piece_justificative_file.virus_scanner.safe? || piece_justificative_file.virus_scanner.pending?)
|
||||||
piece_justificative_file.service_url
|
piece_justificative_file.service_url
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Dossier < ApplicationRecord
|
||||||
INSTRUCTION_COMMENCEE = TERMINE + [states.fetch(:en_instruction)]
|
INSTRUCTION_COMMENCEE = TERMINE + [states.fetch(:en_instruction)]
|
||||||
SOUMIS = EN_CONSTRUCTION_OU_INSTRUCTION + TERMINE
|
SOUMIS = EN_CONSTRUCTION_OU_INSTRUCTION + TERMINE
|
||||||
|
|
||||||
TAILLE_MAX_ZIP = 50.megabytes
|
TAILLE_MAX_ZIP = 100.megabytes
|
||||||
|
|
||||||
REMAINING_DAYS_BEFORE_CLOSING = 2
|
REMAINING_DAYS_BEFORE_CLOSING = 2
|
||||||
INTERVAL_BEFORE_CLOSING = "#{REMAINING_DAYS_BEFORE_CLOSING} days"
|
INTERVAL_BEFORE_CLOSING = "#{REMAINING_DAYS_BEFORE_CLOSING} days"
|
||||||
|
@ -131,11 +131,19 @@ class Dossier < ApplicationRecord
|
||||||
etablissement: :champ,
|
etablissement: :champ,
|
||||||
champs: {
|
champs: {
|
||||||
etablissement: :champ,
|
etablissement: :champ,
|
||||||
type_de_champ: :drop_down_list
|
type_de_champ: :drop_down_list,
|
||||||
|
piece_justificative_file_attachment: :blob,
|
||||||
|
champs: [
|
||||||
|
piece_justificative_file_attachment: :blob
|
||||||
|
]
|
||||||
},
|
},
|
||||||
champs_private: {
|
champs_private: {
|
||||||
etablissement: :champ,
|
etablissement: :champ,
|
||||||
type_de_champ: :drop_down_list
|
type_de_champ: :drop_down_list,
|
||||||
|
piece_justificative_file_attachment: :blob,
|
||||||
|
champs: [
|
||||||
|
piece_justificative_file_attachment: :blob
|
||||||
|
]
|
||||||
},
|
},
|
||||||
procedure: :groupe_instructeurs
|
procedure: :groupe_instructeurs
|
||||||
).order(en_construction_at: 'asc')
|
).order(en_construction_at: 'asc')
|
||||||
|
|
54
package.json
54
package.json
|
@ -1,35 +1,35 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/preset-react": "^7.8.3",
|
"@babel/preset-react": "^7.9.4",
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.26",
|
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.12.0",
|
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.8",
|
"@fortawesome/react-fontawesome": "^0.1.9",
|
||||||
"@mapbox/mapbox-gl-draw": "^1.1.2",
|
"@mapbox/mapbox-gl-draw": "^1.1.2",
|
||||||
"@rails/actiontext": "^6.0.2-1",
|
"@rails/actiontext": "^6.0.3",
|
||||||
"@rails/activestorage": "^6.0.2-1",
|
"@rails/activestorage": "^6.0.3",
|
||||||
"@rails/ujs": "^6.0.2-1",
|
"@rails/ujs": "^6.0.3",
|
||||||
"@rails/webpacker": "4.2.2",
|
"@rails/webpacker": "5.1.1",
|
||||||
"@reach/combobox": "^0.10.0",
|
"@reach/combobox": "^0.10.2",
|
||||||
"@sentry/browser": "^5.11.2",
|
"@sentry/browser": "^5.15.5",
|
||||||
"@tmcw/togeojson": "^4.0.0",
|
"@tmcw/togeojson": "^4.0.0",
|
||||||
"@turf/area": "^6.0.1",
|
"@turf/area": "^6.0.1",
|
||||||
"babel-plugin-macros": "^2.8.0",
|
"babel-plugin-macros": "^2.8.0",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||||
"chartkick": "^3.2.0",
|
"chartkick": "^3.2.0",
|
||||||
"core-js": "^3.6.4",
|
"core-js": "^3.6.5",
|
||||||
"debounce": "^1.2.0",
|
"debounce": "^1.2.0",
|
||||||
"dom4": "^2.1.5",
|
"dom4": "^2.1.5",
|
||||||
"email-butler": "^1.0.13",
|
"email-butler": "^1.0.13",
|
||||||
"highcharts": "^8.0.0",
|
"highcharts": "^8.1.0",
|
||||||
"intersection-observer": "^0.7.0",
|
"intersection-observer": "^0.10.0",
|
||||||
"jquery": "^3.5.0",
|
"jquery": "^3.5.1",
|
||||||
"leaflet": "^1.6.0",
|
"leaflet": "^1.6.0",
|
||||||
"leaflet-freedraw": "^2.12.0",
|
"leaflet-freedraw": "^2.12.0",
|
||||||
"mapbox-gl": "^1.9.0",
|
"mapbox-gl": "^1.10.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.12.0",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.12.0",
|
"react-dom": "^16.13.1",
|
||||||
"react-intersection-observer": "^8.25.2",
|
"react-intersection-observer": "^8.26.2",
|
||||||
"react-loadable": "^5.5.0",
|
"react-loadable": "^5.5.0",
|
||||||
"react-mapbox-gl": "^4.8.3",
|
"react-mapbox-gl": "^4.8.3",
|
||||||
"react-mapbox-gl-draw": "^2.0.4",
|
"react-mapbox-gl-draw": "^2.0.4",
|
||||||
|
@ -37,20 +37,20 @@
|
||||||
"react-sortable-hoc": "^1.11.0",
|
"react-sortable-hoc": "^1.11.0",
|
||||||
"react_ujs": "^2.6.1",
|
"react_ujs": "^2.6.1",
|
||||||
"select2": "^4.0.13",
|
"select2": "^4.0.13",
|
||||||
"trix": "^1.2.2",
|
"trix": "^1.2.3",
|
||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^10.0.3",
|
"babel-eslint": "^10.1.0",
|
||||||
"eclint": "^2.8.1",
|
"eclint": "^2.8.1",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^7.0.0",
|
||||||
"eslint-config-prettier": "^6.10.0",
|
"eslint-config-prettier": "^6.11.0",
|
||||||
"eslint-plugin-prettier": "^3.1.2",
|
"eslint-plugin-prettier": "^3.1.3",
|
||||||
"eslint-plugin-react": "^7.18.0",
|
"eslint-plugin-react": "^7.20.0",
|
||||||
"eslint-plugin-react-hooks": "^2.3.0",
|
"eslint-plugin-react-hooks": "^4.0.2",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "^2.0.5",
|
||||||
"webpack-bundle-analyzer": "^3.6.0",
|
"webpack-bundle-analyzer": "^3.7.0",
|
||||||
"webpack-dev-server": "^3.10.0"
|
"webpack-dev-server": "^3.11.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint:ec": "eclint check $({ git ls-files | grep -v app/graphql/schema.graphql ; find vendor -type f ; echo 'db/schema.rb' ; } | sort | uniq -u)",
|
"lint:ec": "eclint check $({ git ls-files | grep -v app/graphql/schema.graphql ; find vendor -type f ; echo 'db/schema.rb' ; } | sort | uniq -u)",
|
||||||
|
|
|
@ -14,6 +14,18 @@ describe Champs::PieceJustificativeChamp do
|
||||||
it { is_expected.to validate_content_type_of(:piece_justificative_file).allowing(Champs::PieceJustificativeChamp::ACCEPTED_FORMATS) }
|
it { is_expected.to validate_content_type_of(:piece_justificative_file).allowing(Champs::PieceJustificativeChamp::ACCEPTED_FORMATS) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#for_export" do
|
||||||
|
let(:champ_pj) { create(:champ_piece_justificative) }
|
||||||
|
subject { champ_pj.for_export }
|
||||||
|
|
||||||
|
it { is_expected.to eq('toto.txt') }
|
||||||
|
|
||||||
|
context 'without attached file' do
|
||||||
|
before { champ_pj.piece_justificative_file.purge }
|
||||||
|
it { is_expected.to eq(nil) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#for_api' do
|
describe '#for_api' do
|
||||||
let(:champ_pj) { create(:champ_piece_justificative) }
|
let(:champ_pj) { create(:champ_piece_justificative) }
|
||||||
let(:metadata) { champ_pj.piece_justificative_file.blob.metadata }
|
let(:metadata) { champ_pj.piece_justificative_file.blob.metadata }
|
||||||
|
|
Loading…
Reference in a new issue