diff --git a/docs/3.0.0-beta.x/concepts/middlewares.md b/docs/3.0.0-beta.x/concepts/middlewares.md index c2b75ea98d..a404fdb281 100644 --- a/docs/3.0.0-beta.x/concepts/middlewares.md +++ b/docs/3.0.0-beta.x/concepts/middlewares.md @@ -178,7 +178,7 @@ Load a middleware at the very first place { "timeout": 100, "load": { - "before": ["time", "responseTime", "logger", "cors", "responses", "gzip"], + "before": ["timer", "responseTime", "logger", "cors", "responses", "gzip"], "order": [ "Define the middlewares' load order by putting their name in this array is the right order" ], diff --git a/packages/strapi-plugin-content-manager/admin/src/translations/de.json b/packages/strapi-plugin-content-manager/admin/src/translations/de.json index 6d69ca95a2..48a6065d13 100644 --- a/packages/strapi-plugin-content-manager/admin/src/translations/de.json +++ b/packages/strapi-plugin-content-manager/admin/src/translations/de.json @@ -24,7 +24,7 @@ "containers.Edit.clickToJump": "Klicke, um zu einem Eintrag zu springen", "containers.Edit.delete": "Löschen", "containers.Edit.editing": "Bearbeite...", - "containers.Edit.reset": "Abbrechen", + "containers.Edit.reset": "Zurücksetzen", "containers.Edit.returnList": "Zu Liste zurückkehren", "containers.Edit.seeDetails": "Details", "containers.Edit.submit": "Speichern", diff --git a/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js b/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js index d3c474cd7d..a71925e75d 100644 --- a/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js @@ -172,7 +172,7 @@ const EditForm = forwardRef( try { const file = await getCroppedResult(); - onSubmitEdit(e, shouldDuplicate, file); + onSubmitEdit(e, shouldDuplicate, file, true); } catch (err) { // Silent } finally { diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepper/InputModalStepper.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepper/InputModalStepper.js index dce8647eb4..8fb5f73c50 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepper/InputModalStepper.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepper/InputModalStepper.js @@ -10,7 +10,7 @@ import stepper from './stepper'; import useModalContext from '../../hooks/useModalContext'; const InputModalStepper = ({ isOpen, onToggle, noNavigation, onInputMediaChange }) => { - const { formatMessage } = useGlobalContext(); + const { emitEvent, formatMessage } = useGlobalContext(); const [shouldDeleteFile, setShouldDeleteFile] = useState(false); const [displayNextButton, setDisplayNextButton] = useState(false); const { @@ -62,6 +62,8 @@ const InputModalStepper = ({ isOpen, onToggle, noNavigation, onInputMediaChange const editModalRef = useRef(); const handleReplaceMedia = () => { + emitEvent('didReplaceMedia', { location: 'upload' }); + editModalRef.current.click(); }; @@ -199,12 +201,20 @@ const InputModalStepper = ({ isOpen, onToggle, noNavigation, onInputMediaChange const handleSubmitEditExistingFile = async ( e, shouldDuplicateMedia = false, - file = fileToEdit.file + file = fileToEdit.file, + isSubmittingAfterCrop = false ) => { e.preventDefault(); submitEditExistingFile(); + if (isSubmittingAfterCrop) { + emitEvent('didCropFile', { + duplicatedFile: shouldDuplicateMedia, + location: 'content-manager', + }); + } + const headers = {}; const formData = new FormData(); diff --git a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js index d74f8e58d7..2d85695ce1 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/InputModalStepperProvider/index.js @@ -34,7 +34,7 @@ const InputModalStepperProvider = ({ step, }) => { const [formErrors, setFormErrors] = useState(null); - const { plugins } = useGlobalContext(); + const { emitEvent, plugins } = useGlobalContext(); const [, updated_at] = getFileModelTimestamps(plugins); const [reducerState, dispatch] = useReducer(reducer, initialState, state => init({ @@ -69,6 +69,11 @@ const InputModalStepperProvider = ({ const downloadFiles = async () => { const files = getFilesToDownload(filesToUpload); + // Emit event when the users download files from url + if (files.length > 0) { + emitEvent('didSelectFile', { source: 'url', location: 'content-manager' }); + } + try { await Promise.all( files.map(file => { @@ -263,6 +268,9 @@ const InputModalStepperProvider = ({ }; const handleSetCropResult = blob => { + // Emit event : the user cropped a file that is not uploaded + emitEvent('didCropFile', { duplicatedFile: null, location: 'content-manager' }); + dispatch({ type: 'SET_CROP_RESULT', blob, @@ -352,6 +360,8 @@ const InputModalStepperProvider = ({ }; const addFilesToUpload = ({ target: { value } }) => { + emitEvent('didSelectFile', { source: 'computer', location: 'content-manager' }); + dispatch({ type: 'ADD_FILES_TO_UPLOAD', filesToUpload: value, diff --git a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js index e1bbb8ae06..4dd079eb29 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ModalStepper/index.js @@ -26,7 +26,7 @@ const ModalStepper = ({ onDeleteMedia, onToggle, }) => { - const { formatMessage } = useGlobalContext(); + const { emitEvent, formatMessage } = useGlobalContext(); const [isWarningDeleteOpen, setIsWarningDeleteOpen] = useState(false); const [shouldDeleteFile, setShouldDeleteFile] = useState(false); const [isFormDisabled, setIsFormDisabled] = useState(false); @@ -74,6 +74,8 @@ const ModalStepper = ({ }, [isOpen]); const addFilesToUpload = ({ target: { value } }) => { + emitEvent('didSelectFile', { source: 'computer', location: 'upload' }); + dispatch({ type: 'ADD_FILES_TO_UPLOAD', filesToUpload: value, @@ -85,6 +87,11 @@ const ModalStepper = ({ downloadFilesRef.current = async () => { const files = getFilesToDownload(filesToUpload); + // Emit event when the users download files from url + if (files.length > 0) { + emitEvent('didSelectFile', { source: 'url', location: 'upload' }); + } + try { await Promise.all( files.map(file => { @@ -255,6 +262,9 @@ const ModalStepper = ({ }; const handleSetCropResult = blob => { + // Emit event : the user cropped a file that is not uploaded + emitEvent('didCropFile', { duplicatedFile: null, location: 'upload' }); + dispatch({ type: 'SET_CROP_RESULT', blob, @@ -274,10 +284,15 @@ const ModalStepper = ({ const handleSubmitEditExistingFile = async ( e, shouldDuplicateMedia = false, - file = fileToEdit.file + file = fileToEdit.file, + isSubmittingAfterCrop = false ) => { e.preventDefault(); + if (isSubmittingAfterCrop) { + emitEvent('didCropFile', { duplicatedFile: shouldDuplicateMedia, location: 'upload' }); + } + dispatch({ type: 'ON_SUBMIT_EDIT_EXISTING_FILE', }); @@ -331,6 +346,7 @@ const ModalStepper = ({ }; const handleReplaceMedia = () => { + emitEvent('didReplaceMedia', { location: 'upload' }); editModalRef.current.click(); }; diff --git a/packages/strapi/lib/middlewares/parser/index.js b/packages/strapi/lib/middlewares/parser/index.js index 2d584fddbb..61e4a29548 100644 --- a/packages/strapi/lib/middlewares/parser/index.js +++ b/packages/strapi/lib/middlewares/parser/index.js @@ -1,17 +1,40 @@ 'use strict'; const body = require('koa-body'); -const qs = require('koa-qs'); +const qs = require('qs'); /** * Body parser hook */ +const addQsParser = app => { + Object.defineProperty(app.request, 'query', { + configurable: false, + enumerable: true, + /* + * Get parsed query-string. + */ + get() { + const qstr = this.querystring; + const cache = (this._querycache = this._querycache || {}); + return cache[qstr] || (cache[qstr] = qs.parse(qstr)); + }, + + /* + * Set query-string as an object. + */ + set(obj) { + this.querystring = qs.stringify(obj); + }, + }); + + return app; +}; + module.exports = strapi => { return { /** * Initialize the hook */ - initialize() { strapi.app.use((ctx, next) => { // disable for graphql @@ -24,7 +47,7 @@ module.exports = strapi => { })(ctx, next); }); - qs(strapi.app); + addQsParser(strapi.app); }, }; }; diff --git a/packages/strapi/package.json b/packages/strapi/package.json index 9d3a3d036d..58f3720580 100644 --- a/packages/strapi/package.json +++ b/packages/strapi/package.json @@ -38,7 +38,6 @@ "koa-ip": "^2.0.0", "koa-locale": "~1.3.0", "koa-lusca": "~2.2.0", - "koa-qs": "^2.0.0", "koa-router": "^7.4.0", "koa-session": "^5.12.0", "koa-static": "^5.0.0", @@ -49,6 +48,7 @@ "node-schedule": "1.3.2", "opn": "^5.3.0", "ora": "^3.0.0", + "qs": "^6.9.3", "resolve-cwd": "^3.0.0", "rimraf": "^2.6.2", "shelljs": "^0.8.3", diff --git a/yarn.lock b/yarn.lock index 5c36f25832..c5721c9898 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11202,14 +11202,6 @@ koa-lusca@~2.2.0: dependencies: koa-compose "~2.3.0" -koa-qs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/koa-qs/-/koa-qs-2.0.0.tgz#18d16b43508a541f092e514351dc09563a48819f" - integrity sha1-GNFrQ1CKVB8JLlFDUdwJVjpIgZ8= - dependencies: - merge-descriptors "~0.0.2" - qs "~2.3.3" - koa-range@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/koa-range/-/koa-range-0.3.0.tgz#3588e3496473a839a1bd264d2a42b1d85bd7feac" @@ -12186,16 +12178,11 @@ meow@^5.0.0: trim-newlines "^2.0.0" yargs-parser "^10.0.0" -merge-descriptors@1.0.1: +merge-descriptors@1.0.1, merge-descriptors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= -merge-descriptors@~0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-0.0.2.tgz#c36a52a781437513c57275f39dd9d317514ac8c7" - integrity sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc= - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -14843,10 +14830,10 @@ qs@^6.4.0, qs@^6.5.1, qs@^6.5.2, qs@^6.9.1: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== -qs@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" - integrity sha1-6eha2+ddoLvkyOBHaghikPhjtAQ= +qs@^6.9.3: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== qs@~6.5.1, qs@~6.5.2: version "6.5.2"