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

Upload whole folders, preserving the nested structure with FileSelector #2189

Closed
5 of 7 tasks
JosuaCarl opened this issue Oct 31, 2024 · 5 comments · Fixed by #2206
Closed
5 of 7 tasks

Upload whole folders, preserving the nested structure with FileSelector #2189

JosuaCarl opened this issue Oct 31, 2024 · 5 comments · Fixed by #2206
Assignees
Labels
🖰 GUI Related to GUI hacktoberfest - 300💎💎💎 Issues rewarded by 300 points hacktoberfest hacktoberfest issues 🆘 Help wanted Open to participation from the community ✨New feature 🟨 Priority: Medium Not blocking but should be addressed

Comments

@JosuaCarl
Copy link
Contributor

JosuaCarl commented Oct 31, 2024

Description

When I want to process MS data, some manufacturers provide the output as folders, with which I want my application to interact. I can however not upload folders as a whole with the file_selector. This limits my ability to integrate my pipeline.

Solution Proposed

  • Add webkitdirectory support for File Selector that mimics the folder structure that is given to it

Impact of Solution

The ability to exclude subfolders (for example via a regular expression or glob) could be important for use cases that want to upload parts of projects.

Additional Context

The folder structure is defined here:
https://github.com/Avaiga/taipy/blob/26e11259c7bce1e04d050460d91323805f4498c9/taipy/gui/gui.py#L1010C1-L1011C4

The FileSelector is implemented here:

const FileSelector = (props: FileSelectorProps) => {
const {
id,
onAction,
defaultLabel = "",
updateVarName = "",
multiple = false,
extensions = ".csv,.xlsx",
dropMessage = "Drop here to Upload",
label,
notify = true,
withBorder = true,
} = props;

and the HTML Element is defined here:
https://github.com/Avaiga/taipy/blob/a131486fbe938acff9de2b0b3961158117b37458/frontend/taipy-gui/src/components/Taipy/FileSelector.tsx#L189C1-L199C13

Acceptance Criteria

  • If applicable, a new demo code is provided to show the new feature in action.
  • Integration tests exhibiting how the functionality works are added.
  • Any new code is covered by a unit tested.
  • Check code coverage is at least 90%.
  • Related issue(s) in taipy-doc are created for documentation and Release Notes are updated.

Code of Conduct

  • I have checked the existing issues.
  • I am willing to work on this issue (optional)
@JosuaCarl
Copy link
Contributor Author

I think I might need some help. I can get the folder structure with webkitdirectory, use uploadFile from fileupload.worker.ts to pass it to __upload_files in gui.py and in case it is not empty, construct the directories as needed with the files landing in the right place. But the problem is, that webkitdirectory is not in React's InputHTMLAttributes, so i tried to extend the module with

declare module "react" {
    interface InputHTMLAttributes<T> extends HTMLAttributes<T> {
      // extends React's HTMLAttributes
      webkitdirectory?: string;
    }
};

This works fine, but when I declare webkitdirectory with

const FileSelector = (props: FileSelectorProps) => {
    const {
        ...
        webkitdirectory = "",
        ...
    } = props;

, as ssuggested here: facebook/react#3468 (comment), the folder selector stays activated in the final HTML, regardless, whether webkitdirectory is present in my markdown or not.

If I declare it like so:

const FileSelector = (props: FileSelectorProps) => {
    const {
        ...
        webkitdirectory,
        ...
    } = props;

the folder selector never appears, even when present in the markdown command chain. I initially tried to set the property to a boolean, but it seems this does not work with React, as it never appears.

A workaround I could picture would be the creation of a separate uploader, but this seems overkill to me.

@JosuaCarl
Copy link
Contributor Author

Ok, I think I got it handled now. It seems I can make a string argument disappear by giving it nothing (like not even None).

@FredLL-Avaiga
Copy link
Member

webkitdirectory is supposed to be a boolean
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory
so you can declare the corresponding property as boolean

@JosuaCarl
Copy link
Contributor Author

webkitdirectory is supposed to be a boolean https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory so you can declare the corresponding property as boolean

Yes it is supposed to be like that, but React will not accept it as such. Believe me, I've tried, and I don't know whether I missed something, but others have seemingly failed as well: facebook/react#3468 (comment)
It is claimed, that it is an issue with it not being whitelisted (whatever that means, I'm not really deep into React).

@FredLL-Avaiga
Copy link
Member

FredLL-Avaiga commented Nov 7, 2024

you can do it like this for now

const directoryProps = props.allowFolder ? {webkitdirectory: "", directory: "", mozdirectory: "", nwdirectory: ""}: undefined
<input type=file  {...directoryProps } />

@jrobinAV jrobinAV added 🖰 GUI Related to GUI 🆘 Help wanted Open to participation from the community 🟨 Priority: Medium Not blocking but should be addressed labels Nov 8, 2024
@FredLL-Avaiga FredLL-Avaiga added hacktoberfest hacktoberfest issues hacktoberfest - 300💎💎💎 Issues rewarded by 300 points labels Nov 13, 2024
jrobinAV pushed a commit that referenced this issue Nov 13, 2024
…ders (#2206)

* Added webkitdirectory to FileSelector

* Added webkitdirectory to factory + testing output in file uploader

* Added webkitdirectory to viselelments.json

* Build files

* Extended InputHTML Attributes to include webkitdirectory

* Extended InputHTML Attributes to include webkitdirectory

* Package locks

* Added webkitRealtivePath to saved blob properties

* Handle webkitdirectory correctly as a string

* Added test for webkitdirectory support

* Addressed linting: E501 + W292

* Addressed failing jest test.

* Changed naming scheme; Used directory to cirumvent naming limitations of React's attribute naming; Adjusted tests for addition of other attributes.

* Added comments to __upload_files() in gui.py; Simplified checks in __upload_files (addresses linter C901) .

* Edited styling of CONTRIBUTING.md for better readability and clarity in execution.

* Normed path

* Changed naming Scheme; Added integration of other directory attributes and changed attribute to boolean.

* Added mandatory case information for python to CONTRIBUTING.md

* Fixed testing caseing.

* Addressed stylistic errors: "W291 [*] Trailing whitespace"; "E711 Comparison to `None` should be `cond is None`"; "W293 [*] Blank line contains whitespace"

* Removed unnecessary ignore

* Deleted unnecessary package-lock

* Restored original package.json in frontend/taipy

* Added test for folder upload.

* Check whether the final directory is a child of the root upload directory.

* Fixed check for upload staying inplace; removed print from test

* Changed path testing to string testing.

* Addressed linter errors.

* Addressed C901 `__upload_files` is too complex (19 > 18)

* Changed unnecessary files to match latest origin commit 37b924f05aba1c814c75098c8ec1750a74e3770

* Changed naming of select_folder to selection_type

* Fixed spelling error; Removed default setting of property; Accounted for different input casing;

---------

Co-authored-by: Fred Lefévère-Laoide <[email protected]>
Co-authored-by: JosuaCarl <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🖰 GUI Related to GUI hacktoberfest - 300💎💎💎 Issues rewarded by 300 points hacktoberfest hacktoberfest issues 🆘 Help wanted Open to participation from the community ✨New feature 🟨 Priority: Medium Not blocking but should be addressed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants