Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Add onRemove props to FileInput so that we can confirm delete action #6998

Closed
tkow opened this issue Dec 15, 2021 · 5 comments

Comments

@tkow
Copy link

tkow commented Dec 15, 2021

Is your feature request related to a problem? Please describe.

FileInput always delete preview components state. So, we can't implement it to confirm logic though we can remove files immediately before submitting form through options.onRemove prop. Also, we can't handle appropriately errors outer of FileInput if we have removing files' errors, because we can't restore previous ui state having state removed completely before handling errors.

Describe the solution you'd like
A solution is that we could add onRemove props FileInput it is different from options.onRemove for back compatibility and this function allow to return boolean or Promise<boolean>. This function is called before file input state removed, then when this returned value is false, interrupt removing state like this.

   const {
    onRemove: onRemoveFromProp,
     ...others
   } = props

    const onRemove = file => async () => {
        const removeCancel = !(await onRemoveFromProp(file))
        if(removeCancel) return

        if (multiple) {
            const filteredFiles = files.filter(
                stateFile => !shallowEqual(stateFile, file)
            );
            onChange(filteredFiles as any);
        } else {
            onChange(null);
        }

        if (options.onRemove) {
            options.onRemove(file);
        }
    };

Describe alternatives you've considered
Enable to replace all children components of FileInput.

Additional context

@fzaninotto
Copy link
Member

Good idea! The core team won't work on it for the foreseeable future, but any third-paty contribution is welcome.
If anyone feels like tackling this, please open a PR against the next branch.

@tkow
Copy link
Author

tkow commented Dec 16, 2021

@fzaninotto
Thank you, I just need the feature in our project so I'll try to implement it with some improvements above codes if no one do that before my work have done.

@andrico1234
Copy link
Contributor

We've come across the same problem recently too.

Until recently, the list of files to be uploaded would get removed after firing a refresh in the onSuccess handler, but now this doesn't seem to be the case. I believe that it was working at 3.19.0, but not since upgrading to 3.19.3.

@tkow
Copy link
Author

tkow commented Dec 21, 2021

@fzaninotto
This feature is implemented in this PR and this does not have any breaking compatibility. Could you review it?

I make it work using confirm dialog with promise handling by the component in the PR.

// ... partial hooks code
const [removeImageConfirmEvent, setRemoveFileConfirmEvent] =
    useState<any>(null);
const [isRemoveImageModalOpen, setIsRemoveImageModalOpen] = useState(false);

// ... partial render code
<ImageInput
          source={PROPERTIES.images}
          src="image"
          validateFileRemoval={(file: any, record: any) => {
            const promise = new Promise<boolean>((_resolve, reject) => {
              setRemoveFileConfirmEvent({
                fileName: `ReviewImage ID: ${file.id}`,
                resolve: async (result: boolean) => {
                  await Api.deleteReviewImages({ ids: [file.id] });
                  return _resolve(result);
                },
                reject,
              });
            });
            setIsRemoveImageModalOpen(true);
            return promise.then((result: boolean) => { 
              // Success Action if you want
            });
          }}
/>

 <FormDataConsumer>
          {({
            formData, // The whole form data
            scopedFormData, // The data for this item of the ArrayInput
            getSource, // A function to get the valid source inside an ArrayInput
            ...rest
          }) => (
            <SomeConfirmModal
              isOpen={isRemoveImageModalOpen}
              title="delete image"
              message={`${
                removeImageConfirmEvent?.fileName} will be deleted`}
              onSubmit={() => {
                setIsRemoveImageModalOpen(false);
                removeImageConfirmEvent?.resolve();
              }}
              onClose={() => {
                setIsRemoveImageModalOpen(false);
                removeImageConfirmEvent?.reject();
              }}
            />
          )}
</FormDataConsumer>

@fzaninotto
Copy link
Member

Fixed by #7003

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants