Skip to content

feat(file-picker): add reference selection mode - #4085

Draft
doubleface wants to merge 3 commits into
masterfrom
feat/file-picker-reference-option
Draft

doubleface wants to merge 3 commits into
masterfrom
feat/file-picker-reference-option

Conversation

@doubleface

Copy link
Copy Markdown
Contributor

Allow PICK intents to return plain file references without generating sharing or download links. Keep the action opt-in, support folder-only constraints and multiple selection, and document the payload for callers.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 784739f8-d8c7-416c-8dc4-6849f126d62d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/file-picker-reference-option

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@doubleface
doubleface requested a review from paultranvan July 22, 2026 15:24
codescene-delta-analysis[bot]

This comment was marked as outdated.

@bundlemon

bundlemon Bot commented Jul 22, 2026

Copy link
Copy Markdown

BundleMon

Files updated (3)
Status Path Size Limits
static/js/intents.(hash).js
18.33KB (+127B +0.68%) -
static/js/main.(hash).js
57.99KB (+42B +0.07%) -
static/js/public.(hash).js
27.14KB (+22B +0.08%) -
Unchanged files (15)
Status Path Size Limits
static/js/(chunkId).(hash).js
767.24KB -
static/resource/(hash).js
336.09KB -
services/qualificationMigration.js
275.6KB -
services/dacc.js
255.74KB -
static/js/lib-react.(hash).js
43.88KB -
static/js/lib-polyfill.(hash).js
22.76KB -
static/js/lib-router.(hash).js
21.92KB -
static/css/main.(hash).css
13.99KB -
static/js/async/(chunkId).(hash).js
7.5KB -
manifest.webapp
6.02KB -
static/css/public.(hash).css
2.71KB -
index.html
809B -
public/index.html
756B -
intents/index.html
681B -
assets/manifest.json
185B -

Total files change +192B +0.01%

Groups updated (1)
Status Path Size Limits
**/*.js
6.15MB (+418B +0.01%) -
Unchanged groups (2)
Status Path Size Limits
**/*.{png,svg,ico}
2.16MB -
**/*.css
73.58KB -

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

disabled: true,
reasonKey: 'FilePicker.constraints.disabledReasons.fileNotAllowed'
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we use the "allowedMimeTypes" parameters?

I don't understand the needs of allowFolder & onlyFolder .

@doubleface doubleface Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mime type only apply to files and not folders then I think we will need a specific option anyway. Or should we create our own custom mime type for folders ? I don't think so

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the adaptation from another branch from @paultranvan who did not have all the context. That is why this PR is still in draft. There is still some work to make it more compliant with the spec. I actually think onlyFolder or equivalent should not be only in reference section.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have : image/** why not folder/** or io.cozy.files:folder or things like that?

Bu we should not add more attributes.

@Crash-- Crash-- Jul 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding onlyFolder (and keeping allowFolder), I'd rather collapse the whole "what can be selected" constraint into a single field. file and folder become symmetric tokens, and mime globs narrow within files. Two options:

Option A - flat accept list

"accept": ["folder"]                     // folders only
"accept": ["file"]                       // any file
"accept": ["image/*", "application/pdf"] // images + PDF only
"accept": ["folder", "image/*"]          // folders or images

Rule: a token without / matches the doctype (file/folder); a token with / is a mime glob (implies a file).

Option B - structured match list

"match": [{ "type": "folder" }, { "mime": "image/*" }]

More verbose, but self-documenting and extensible to other fields later (class, tags, size).

In both cases it's an OR across entries (item allowed if it matches any), and this replaces allowFolder + onlyFolder + allowedMimeTypes with one field. Absent = ["file", "folder"] (permissive).

@zatteo If we were only for stack, I would go for Option B. It's way more flexible & extensible. But with openburo in mind, maybe we should take Option A? What is your opinion? And in this case, it could still be acceptedMimeTypes

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a good point that:

  • we don't have any mimetype for folders in cozy-stack
  • but the client of the file picker don't care

class or tags or favorite are internal drive metadata. So indeed, to stay close to what openburo could look like, we should go to option A that does not expose any internal and stay simple.

For class or tags or favorite, it is maybe more a filter in the file picker itself that could help, like a "favorite" checkbox or tab in the file picker itself if we want to quickly see favorite. I don't see any usecase where we want to force the user to select a favorite.

About size, we have the max size for a file but also the max size for all files that is a mail requirement. The max size for all files would be complicated to insert in this match so we still need size management outside of this.

So I would go to A right now. In anycase I like the accept name that is explicit & generic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept option avoid the confusion with mime type and is really clear. And since we have to avoid to expose any internal, option A looks good.

For class or tags or favorite, it is maybe more a filter in the file picker itself that could help, like a "favorite" checkbox or tab in the file picker itself if we want to quickly see favorite. I don't see any usecase where we want to force the user to select a favorite.

Since we will have a tab for recents for example, we could have a tab for favorites also. And those filters look more like something to help the user to find the files he wants to pick.

If we agree, I could update the spec

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

application/x-directory if it help somehow

"reference": {
"label": "Select",
"onlyFolder": true
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you call reference? Only the io.cozy.files document?

I don't like the naming, but I've nothing yet to suggest.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we call a reference is "doctype + _id". Since the file picker will on return files or folder, I suppose we could remove the doctype part.

Maybe we could replace the reference with identifier ?

@Crash-- Crash-- Jul 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like identifier specially because I've that in mind: #4085 (comment)

@doubleface doubleface Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, and if we want to return the full document, we could call it documents ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's identifier with type, it can be doc as everywhere in stack, json, data, obj if we want to return the whole json doc

Comment thread docs/file-picker-intent.md Outdated
Comment thread src/modules/services/components/FilePicker/FilePickerFooter.jsx Outdated
Comment thread src/modules/services/components/FilePicker/index.jsx Outdated
Comment thread docs/file-picker-intent.md Outdated
sharingLink?: string
downloadLink?: string
type?: string
doctype?: 'io.cozy.files'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why it's not the full FileDoctype Type from cozy-client?

@doubleface doubleface Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Then, if we return the full document, we could replace reference simply with documents (since we may return multiple documents) ?

...(downloadLink ? { downloadLink } : {})
...(downloadLink ? { downloadLink } : {}),
...(reference ? { type: file.type, doctype: 'io.cozy.files' } : {})
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we ask a "reference" we should return the reference. So the complete io.cozy.files.

I'm wondering if we should not do the same for the other actions.

It should be caller responsibility to ask only specific fields.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we really want to achieve with reference is to not create a sharing or download link right @doubleface ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should not do the same for the other actions.

Good question, should we always return the full io.cozy.files and in some case "more" like a download link or a sharing link?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think yes. And if the caller do not need to handle the full io.cozy.files, then it can specified the desired attributes (because for exemple, a note is a big io.cozy.files...). No?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we really want to achieve with reference is to not create a sharing or download link right @doubleface ?

yes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should not use this "reference" mode if there is any action set by the caller. Maybe it should be the default one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should not use this "reference" mode if there is any action set by the caller. Maybe it should be the default one.

Agree!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. The default action should be the one with no side effect

@doubleface
doubleface force-pushed the feat/file-picker-reference-option branch from d37f96e to 3e05778 Compare July 23, 2026 10:14
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@doubleface
doubleface force-pushed the feat/file-picker-reference-option branch from 4384fbb to 5721916 Compare July 23, 2026 13:15
codescene-delta-analysis[bot]

This comment was marked as outdated.

@doubleface
doubleface force-pushed the feat/file-picker-reference-option branch from 5721916 to fdf1d83 Compare July 23, 2026 13:59
codescene-delta-analysis[bot]

This comment was marked as outdated.

@doubleface doubleface added e2e Run the E2E suite on this PR and removed e2e Run the E2E suite on this PR labels Jul 23, 2026
codescene-delta-analysis[bot]

This comment was marked as outdated.

@zatteo

zatteo commented Jul 27, 2026

Copy link
Copy Markdown
Member

I like it a lot with this new specification. Even if sometimes the io.cozy.files document can return a lot of data, e.g. with a cozy-notes, I consider this as a feature for now. We will see in the future if sometimes we send too much data but there is no reason otherwise to not send the entire io.cozy.files document.

Comment thread docs/file-picker-intent.md Outdated
Comment thread docs/file-picker-intent.md Outdated
"sharingLink": { "label": "Share as link" },
"doc": {
"label": "Select",
"accept": ["folder"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so no x-directory?

@zatteo zatteo Jul 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am skeptical about application/x-directory as it is non standard and we still need a custom value for "all files" so it does not solve entirely our problem.

Or maybe creating our own ones?

  • application/vnd.twake.file => means all files
  • application/vnd.twake.folder => means all folders

It fit in mimetype mental model and allow custom needs.

Comment thread docs/file-picker-intent.md Outdated
Comment thread docs/file-picker-intent.md Outdated
Allow PICK intents to return plain file references without generating sharing or download links. Keep the action opt-in, support folder-only constraints and multiple selection, and document the payload for callers.
Expose selected Cozy documents without mapping fields so callers receive
cozy-client's complete file and folder shape. Rename the action to
`documents` to reflect its array result.
@doubleface
doubleface force-pushed the feat/file-picker-reference-option branch from 87fd8fb to 22548d0 Compare July 28, 2026 13:21

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Health Improved (1 files improve in Code Health)

Our agent can fix these. Install it.

Gates Passed
3 Quality Gates Passed

View Improvements
File Code Health Impact Categories Improved
FilePickerFooter.jsx 9.69 → 10.00 Excess Number of Function Arguments

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants