The GitHub Actions job "Required Checks" on 
texera.git/gh-readonly-queue/main/pr-8352-d09186855d1da1b3d188689d68ae93a57d87bc75
 has succeeded.
Run started by GitHub user aicam (triggered by aicam).

Head commit for run:
905c17d93e0975eb501581aab3716f9e98a50b0d / Tanishq Gandhi 
<[email protected]>
feat(frontend): gate the file tree's delete and cover controls on write access 
(#8352)

### What changes were proposed in this PR?

A collaborator with READ access saw write controls in the file tree.
Nothing insecure happened — the backend rejects the calls — but the
buttons should not be offered:

- On a dataset shared READ-only, every file row showed a delete (trash)
icon: the page bound `[isTreeNodeDeletable]="true"` unconditionally.
- On **both** the dataset and the model page, an image row showed "Set
as cover", because the shared file tree gated that button on
`isImageFile(...)` and nothing else. Clicking it returned a red "User
has no access to this dataset" toast.

Changes:

- `user-dataset-version-filetree.component.ts/.html` — a new
`isCoverSettable` input, defaulting to `false` exactly like
`isTreeNodeDeletable`, added to the "Set as cover" `*ngIf`.
- `dataset-detail.component.html` — bind both inputs to
`userHasWriteAccess()`, the helper that already gates the Settings tab,
instead of the hardcoded `true`.
- `model-detail.component.html` — bind the new input to its own
`userHasWriteAccess()`. The model page already gated delete this way.

The third consumer of the tree, `dataset-selection-modal`, binds neither
input and so now renders no "Set as cover" button — it never wired the
output up, so that button did nothing at all before.


Verified against a local stack with a dataset and a model shared
READ-only with a second user:

| | delete icons | "Set as cover" |
| --- | --- | --- |
| dataset, READ user, before | 4 | 1 |
| dataset, READ user, after | 0 | 0 |
| model, READ user, before | 0 | 1 |
| model, READ user, after | 0 | 0 |
| dataset, owner, after | 4 | 1 |

**Before** — READ-only collaborator sees a trash icon on every file, and
"Set as cover" gives a 403:

<img width="1440" height="900" alt="image"
src="https://github.com/user-attachments/assets/5ca2c137-2457-4a8b-8178-2a0347fab0d7";
/>
<img width="1440" height="900" alt="image"
src="https://github.com/user-attachments/assets/227c2547-a332-42ea-97a6-9560bc2d7435";
/>

**After** — the same user, same dataset, no write controls (the owner's
view is unchanged):

<img width="1440" height="900" alt="image"
src="https://github.com/user-attachments/assets/87d76d20-0e18-4017-a9d4-045b1615c4b0";
/>

### Any related issues, documentation, discussions?

Closes #8349.

### How was this PR tested?

Specs added or updated:

- `user-dataset-version-filetree.component.spec.ts` — new `withholds
Set-as-cover unless the host allows it`; the existing `offers
Set-as-cover on image files only` now opts in through the new input. 18
passed.
- `dataset-detail.component.spec.ts` — new `offers the tree's write
controls only to a writer`, asserting both inputs follow WRITE/READ. 143
passed.
- `model-detail.component.spec.ts` — the same case for the model page.
81 passed.
- `dataset-selection-modal.component.spec.ts` — unchanged, 16 passed.

```
cd frontend
npx ng test --include 
src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.spec.ts
npx ng test --include 
src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.spec.ts
npx ng test --include 
src/app/dashboard/component/user/user-model/user-model-explorer/model-detail.component.spec.ts
```

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

Report URL: https://github.com/apache/texera/actions/runs/33810271671

With regards,
GitHub Actions via GitBox

Reply via email to