diff --git a/web/client/components/import/dragZone/enhancers/__tests__/useFiles-test.js b/web/client/components/import/dragZone/enhancers/__tests__/useFiles-test.js index e9ae7ca75d..98a924f650 100644 --- a/web/client/components/import/dragZone/enhancers/__tests__/useFiles-test.js +++ b/web/client/components/import/dragZone/enhancers/__tests__/useFiles-test.js @@ -184,6 +184,56 @@ describe('useFiles enhancer', () => { ReactDOM.render(, document.getElementById("container")); + }); + it('useFiles rendering with layer having size exceed the max limit should call warnig()', (done) => { + const handlers = { + warning: () => {}, + onClose: () => {}, + loadAnnotations: () => {}, + loadMap: () => {} + }; + const warningSpy = expect.spyOn(handlers, 'warning'); + + const actions = { + setLayers: (layers) => { + expect(layers).toExist(); + // length is 1 since just one layer is valid and the another is invalid for its size + expect(layers.length).toBe(1); + expect(warningSpy).toHaveBeenCalled(); + done(); + } + }; + + const sink = createSink( props => { + expect(props).toExist(); + expect(props.layers).toExist(); + expect(props.useFiles).toExist(); + props.useFiles({layers: props.layers}); + + }); + const EnhancedSink = useFiles(sink); + + const layers = [{ + type: 'vector', name: "FileName", hideLoading: true, + bbox: {crs: "EPSG:4326"}, + "features": [{ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [-20, 30] + }, + "properties": { + "prop0": "value0" + } + }] + }, { + type: 'vector', name: "FileName01", hideLoading: true, + exceedFileMaxSize: true, + "features": [] + }]; + ReactDOM.render(, document.getElementById("container")); + }); it('useFiles rendering with new annotation layer', (done) => { diff --git a/web/client/components/import/dragZone/enhancers/processFiles.jsx b/web/client/components/import/dragZone/enhancers/processFiles.jsx index 9afc0b2fae..67138db7f7 100644 --- a/web/client/components/import/dragZone/enhancers/processFiles.jsx +++ b/web/client/components/import/dragZone/enhancers/processFiles.jsx @@ -12,7 +12,7 @@ import { compose, createEventHandler, mapPropsStream } from 'recompose'; import Rx from 'rxjs'; import { isAnnotation, importJSONToAnnotations } from '../../../../plugins/Annotations/utils/AnnotationsUtils'; -import ConfigUtils from '../../../../utils/ConfigUtils'; +import ConfigUtils, { getConfigProp } from '../../../../utils/ConfigUtils'; import { MIME_LOOKUPS, checkShapePrj, @@ -25,7 +25,8 @@ import { readZip, recognizeExt, shpToGeoJSON, - readGeoJson + readGeoJson, + isFileSizeExceedMaxLimit } from '../../../../utils/FileUtils'; import { geoJSONToLayer } from '../../../../utils/LayersUtils'; @@ -66,6 +67,17 @@ const checkFileType = (file) => { const readFile = (onWarnings) => (file) => { const ext = recognizeExt(file.name); const type = file.type || MIME_LOOKUPS[ext]; + // Check the file size first before file conversion process to avoid this useless effort + const isVectorFileSizeConfigurable = getConfigProp('importedVectorFileSizeInMB'); + const isVectorFile = type !== 'application/json'; // skip json as json is for map file + if (isVectorFileSizeConfigurable && isVectorFile) { + const fileSizeLimitInMB = getConfigProp('importedVectorFileSizeInMB'); + if (isFileSizeExceedMaxLimit(file, fileSizeLimitInMB)) { + // add 'exceedFileMaxSize' and fileSizeLimitInMB into layer object to be used in useFiles + return [[{ "type": "FeatureCollection", features: [], "fileName": file.name, exceedFileMaxSize: true, fileSizeLimitInMB }]]; + } + } + const projectionDefs = ConfigUtils.getConfigProp('projectionDefs') || []; const supportedProjections = (projectionDefs.length && projectionDefs.map(({code}) => code) || []).concat(["EPSG:4326", "EPSG:3857", "EPSG:900913"]); if (type === 'application/vnd.google-earth.kml+xml') { @@ -193,5 +205,6 @@ export default compose( }) ); } + ) ); diff --git a/web/client/components/import/dragZone/enhancers/useFiles.js b/web/client/components/import/dragZone/enhancers/useFiles.js index 80d8e93b8b..68f725895b 100644 --- a/web/client/components/import/dragZone/enhancers/useFiles.js +++ b/web/client/components/import/dragZone/enhancers/useFiles.js @@ -39,9 +39,18 @@ export default compose( } else { let validLayers = []; layers.forEach((layer) => { - const valid = layer.type === "vector" ? checkIfLayerFitsExtentForProjection(layer) : true; + const isFileSizeNotValid = !!layer?.exceedFileMaxSize; // this check is for file size limit for vector layer + const valid = layer.type === "vector" ? (checkIfLayerFitsExtentForProjection(layer) && !isFileSizeNotValid) : true; if (valid) { validLayers.push(layer); + } else if (isFileSizeNotValid) { + warning({ + title: "notification.warning", + message: "mapImport.errors.exceedFileSizeLimit", + autoDismiss: 6, + position: "tc", + values: {filename: layer.name ?? " ", maxfilesize: layer?.fileSizeLimitInMB ?? 10} + }); } else { warning({ title: "notification.warning", diff --git a/web/client/translations/data.de-DE.json b/web/client/translations/data.de-DE.json index 5c61e664ab..59fee249a7 100644 --- a/web/client/translations/data.de-DE.json +++ b/web/client/translations/data.de-DE.json @@ -1583,7 +1583,8 @@ "fileNotSupported": "Datei wird nicht unterstützt", "unknownError": "Beim Import ist ein unbekannter Fehler aufgetreten", "projectionNotSupported": "Die Projektion der Datei, die Sie importieren möchten, wird nicht unterstützt", - "fileBeyondBoundaries": "Die Datei {Dateiname} kann nicht importiert werden, da sie nicht zu den Kartengrenzen passt" + "fileBeyondBoundaries": "Die Datei {Dateiname} kann nicht importiert werden, da sie nicht zu den Kartengrenzen passt", + "exceedFileSizeLimit": "Die Datei {filename}, die Sie importieren möchten, überschreitet die maximale Dateigröße von {maxfilesize} MB" } }, "mapExport": { diff --git a/web/client/translations/data.en-US.json b/web/client/translations/data.en-US.json index 02595d66d6..bc50d86d48 100644 --- a/web/client/translations/data.en-US.json +++ b/web/client/translations/data.en-US.json @@ -1544,6 +1544,7 @@ "fileNotSupported": "File not supported", "unknownError": "there was an unknown error during import", "projectionNotSupported": "The projection of the file(s) you're trying to import is not supported", + "exceedFileSizeLimit": "The file {filename} you're trying to import is exceeded the max file size limit {maxfilesize} MB", "fileBeyondBoundaries": "The file {filename} cannot be imported because it does not fit the map boundaries" } }, diff --git a/web/client/translations/data.es-ES.json b/web/client/translations/data.es-ES.json index 95460de5c8..4c3f57ab7a 100644 --- a/web/client/translations/data.es-ES.json +++ b/web/client/translations/data.es-ES.json @@ -1545,7 +1545,8 @@ "fileNotSupported": "Archivo no compatible", "unknownError": "hubo un error desconocido durante la importación", "projectionNotSupported": "La proyección del archivo que está intentando importar no es compatible", - "fileBeyondBoundaries": "El archivo {filename} no se pudo importar porque no encaja dentro de los límites del mapa" + "fileBeyondBoundaries": "El archivo {filename} no se pudo importar porque no encaja dentro de los límites del mapa", + "exceedFileSizeLimit": "El archivo {filename} que estás intentando importar ha superado el límite máximo de tamaño de archivo {maxfilesize} MB" } }, "mapExport": { diff --git a/web/client/translations/data.fr-FR.json b/web/client/translations/data.fr-FR.json index f1cbd8864b..8c3b6065c9 100644 --- a/web/client/translations/data.fr-FR.json +++ b/web/client/translations/data.fr-FR.json @@ -1545,7 +1545,8 @@ "fileNotSupported": "Fichier non pris en charge", "unknownError": "il y a eu une erreur inconnue lors de l'import", "projectionNotSupported": "La projection du/des fichier(s) que vous essayez d'importer n'est pas prise en charge", - "fileBeyondBoundaries": "Le fichier {filename} ne peut pas être importé car il ne correspond pas aux limites de la carte" + "fileBeyondBoundaries": "Le fichier {filename} ne peut pas être importé car il ne correspond pas aux limites de la carte", + "exceedFileSizeLimit": "Le fichier {filename} que vous essayez d'importer dépasse la limite de taille de fichier maximale {maxfilesize} Mo" } }, "mapExport": { diff --git a/web/client/translations/data.is-IS.json b/web/client/translations/data.is-IS.json index c4dac582a1..52e828ab73 100644 --- a/web/client/translations/data.is-IS.json +++ b/web/client/translations/data.is-IS.json @@ -1425,7 +1425,8 @@ "fileNotSupported": "File not supported", "unknownError": "there was an unknown error during import", "projectionNotSupported": "The projection of the file(s) you're trying to import is not supported", - "fileBeyondBoundaries": "The file {filename} cannot be imported because it does not fit the map boundaries" + "fileBeyondBoundaries": "The file {filename} cannot be imported because it does not fit the map boundaries", + "exceedFileSizeLimit": "The file {filename} you're trying to import is exceeded the max file size limit {maxfilesize} MB" } }, "mapExport": { diff --git a/web/client/translations/data.it-IT.json b/web/client/translations/data.it-IT.json index 8d2905dbc3..405b46067f 100644 --- a/web/client/translations/data.it-IT.json +++ b/web/client/translations/data.it-IT.json @@ -1542,7 +1542,8 @@ "fileNotSupported": "File non supportato", "unknownError": "si è verificato un errore sconosciuto durante l'importazione", "projectionNotSupported": "La proiezione del file che stai tentando di importare non è supportata", - "fileBeyondBoundaries": "Il file {nomefile} non può essere importato perché non si adatta ai confini della mappa" + "fileBeyondBoundaries": "Il file {nomefile} non può essere importato perché non si adatta ai confini della mappa", + "exceedFileSizeLimit": "Il file {filename} che stai tentando di importare ha superato il limite massimo di dimensione file {maxfilesize} MB" } }, "mapExport": { diff --git a/web/client/utils/FileUtils.js b/web/client/utils/FileUtils.js index e58fa75a50..5860c8254b 100644 --- a/web/client/utils/FileUtils.js +++ b/web/client/utils/FileUtils.js @@ -180,3 +180,15 @@ export const checkShapePrj = function(buffer) { }); }); }; + +/** + * Checks if the file size exceeds the size limit or not. Returns true if exceeding the limit and false if not. + */ +export const isFileSizeExceedMaxLimit = (file, fileSizeLimitInMb) => { + const fileSizeLimitInByte = fileSizeLimitInMb * 1024 * 1024; + const fileSizeInBype = file.size; + if (fileSizeInBype <= fileSizeLimitInByte) { + return false; + } + return true; +}; diff --git a/web/client/utils/__tests__/FileUtils-test.js b/web/client/utils/__tests__/FileUtils-test.js index b554555d60..5de39f8095 100644 --- a/web/client/utils/__tests__/FileUtils-test.js +++ b/web/client/utils/__tests__/FileUtils-test.js @@ -7,7 +7,7 @@ */ import expect from 'expect'; -import {readJson, readZip, checkShapePrj} from '../FileUtils'; +import {readJson, readZip, checkShapePrj, isFileSizeExceedMaxLimit} from '../FileUtils'; import axios from '../../libs/ajax'; describe('FilterUtils', () => { @@ -31,4 +31,16 @@ describe('FilterUtils', () => { }); }); }); + it('isFileSizeExceedMaxLimit with large size exceed the max', () => { + const maxLimitInMega = 1; + const fileWithSizeExceedMaxLimit = 2 * 1024 * 1024; + let isFileSizeValid = isFileSizeExceedMaxLimit({size: fileWithSizeExceedMaxLimit}, maxLimitInMega); + expect(isFileSizeValid).toEqual(true); + }); + it('isFileSizeExceedMaxLimit with small file size less than max', () => { + const maxLimitInMega = 1; + const fileWithSizeNotExceedMaxLimit = 0.5 * 1024 * 1024; + let isFileSizeValid = isFileSizeExceedMaxLimit({size: fileWithSizeNotExceedMaxLimit}, maxLimitInMega); + expect(isFileSizeValid).toEqual(false); + }); });