Se você fizer o upload de um arquivo CSV com tags, o console exibirá um erro após um upload bem-sucedido.
Aqui está uma análise.
O problema subjacente é essencialmente que o modal fecha rápido demais com a lógica atual.
O erro acontece em uppy-upload.js.
As propriedades falharam ao serem definidas porque o elemento (uppy-upload) já foi destruído.
Como isso é possível? this._uppyInstance?.cancelAll();
Para referência, _reset é chamado de _allUploadsComplete.
_reset() {
this._uppyInstance?.cancelAll();
this.setProperties({
uploading: false,
processing: false,
cancellable: false,
uploadProgress: 0,
filesAwaitingUpload: false,
});
No upload bem-sucedido, esta é a ordem das funções:
uploadDone → _allUploadsComplete → [ _reset ]
this._uppyInstance.on("upload-success", (file, response) => {
if (this.usingS3Uploads) {
this.setProperties({ uploading: false, processing: true });
this._completeExternalUpload(file)
.then((completeResponse) => {
this._removeInProgressUpload(file.id);
this.appEvents.trigger(
`upload-mixin:${this.id}:upload-success`,
file.name,
completeResponse
);
this.uploadDone(
deepMerge(completeResponse, { file_name: file.name })
);
this._triggerInProgressUploadsEvent();
if (this.inProgressUploads.length === 0) {
this._allUploadsComplete();
Quando uploadDone é chamado, o modal é fechado imediatamente.
Isso significa que o elemento uppy-upload será destruído no final do frame.
https://github.com/discourse/discourse/blob/main/app/assets/javascripts/admin/addon/components/tags-uploader.js#L22-L26
Voltando a this._uppyInstance?.cancelAll();. Isso acionará o evento abaixo.
Essa é a razão pela qual falha. Por causa de run(), as propriedades serão definidas depois que o elemento for destruído.
this._uppyInstance.on("file-removed", (file, reason) => {
run(() => {
// we handle the cancel-all event specifically, so no need
// to do anything here. this event is also fired when some files
// are handled by an upload handler
if (reason === "cancel-all") {
return;
}
this.appEvents.trigger(
`upload-mixin:${this.id}:upload-cancelled`,
file.id
);
});
});
Esta é uma regressão menor. Introduzida aqui:
uppy-upload.js
main ← dev/uppy-upload-mixin-improvements
opened 11:24PM - 05 Apr 22 UTC
This PR brings the `UppyUploadMixin` more into line with the `ComposerUppyUpload… ` mixin, by extending the `ExtendableUploader` . This also adds better tracking of and events for in progress uploads in the `UppyUploadMixin` for better UI interactions, and also opens up the use of `_useUploadPlugin` for the mixin, so anything implementing `UppyUploadMixin` can add extra uppy preprocessor plugins as needed.
This has been done as part of work on extracting uploads out of the chat composer. In future, we might be able to do the same for `ComposerUppyUpload`, getting rid of that mixin to standardise on `UppyUploadMixin` and have a separate `composer-uploads` component that lives alongside `composer-editor` like what we are doing in https://github.com/discourse/discourse-chat/pull/764
main ← issue/improve-starting-new-uploads-progress
opened 06:48AM - 28 Sep 22 UTC
This commit addresses issues around starting new uploads in a composer etc. when… one or more uploads are already processing or uploading. There were a couple of issues:
1. When all preprocessors were complete, we were not resetting `completeProcessing` to 0, which meant that `needProcessing` would never match `completeProcessing` if a new upload was started.
2. We were relying on the uppy "complete" event which is supposed to fire when all uploads are complete, but this doesn't seem to take into account new uploads that are added. Instead now we can rely on our own `inProgressUploads` tracker, and consider all uploads complete when there are no `inProgressUploads` in flight
This is difficult to test for in JS since it involves the upload lifecycle and AJAX calls, so tests are omitted.
tags-upload.js
main ← a11y-refactor-bootbox-alerts
opened 04:30PM - 20 Sep 22 UTC
Possíveis soluções que funcionam:
Fechar o modal um pouco mais tarde
uploadDone() {
this.refresh();
this.dialog
.alert(I18n.t("tagging.upload_successful"))
.finally(() => this.closeModal());
}
Mover a verificação para fora do loop run().
this._uppyInstance.on("file-removed", (file, reason) => {
// lidamos especificamente com o evento cancel-all, então não há necessidade
// de fazer nada aqui. este evento também é disparado quando alguns arquivos
// são tratados por um manipulador de upload
if (reason === "cancel-all") {
return;
}
run(() => {
Não tenho certeza se existe uma solução melhor. Então, estou postando aqui.
É muito texto para um problema menor e não bloqueante, mas não era evidente inicialmente.