The GitHub Actions job "Required Checks" on texera.git/main has succeeded.
Run started by GitHub user github-merge-queue[bot] (triggered by 
github-merge-queue[bot]).

Head commit for run:
11e3b969a70063d17bfd670b1da85dba100e4339 / Tanishq Gandhi 
<[email protected]>
feat(frontend): add model sharing, publishing and cover images (#8299)

### What changes were proposed in this PR?

Models can now be shared, published and given a cover image. The three
surfaces that grew a per-type branch for each new resource kind move
onto the resource-descriptor registry instead, so the model arm is a
descriptor rather than another `if (type === ...)`.

**Refactor:** `ResourceDescriptor` gains `isPublic`/`setPublished`,
`coverUrl`/`setCover` and `affordances`. `ShareAccessComponent`'s four
publish/unpublish methods become one `setPublished(next)`, and it stops
injecting `WorkflowPersistService` and `DatasetService`. `card-item` and
`list-item` build one share-modal config instead of two and gate the
Share button on the descriptor, which retires the dead button on file
cards.
`browse-section` asks the descriptor for a cover instead of
concatenating a URL, so a dataset's cover is the same picture in the hub
as on its card, and it no longer needs a per-kind branch to add one.

**Feature:** `ModelService` gains publicity, downloadable, cover and
owners calls; the model detail page gets an **Access & visibility**
card; and the file tree's existing "Set as cover" control is wired up.

Four deliberate behavior changes, worth a reviewer's attention:

- Publishing a **dataset or model** no longer warns about "the right to
clone your work". Only workflows are clonable — `cloneWorkflow` is the
only clone in the codebase, and `cloneCount` is hardcoded to 0 for every
other kind — so datasets were being warned about a capability that does
  not exist.
- The share modal's Private card read `this workflow {{ type }}`,
rendering "this workflow dataset". The stray word is removed.
- A `file`-typed share email no longer appends a broken `<origin>/<id>`
link, since the file descriptor has no private route.
- **Publishing and download permission now report the state the server
ended up in, not the one that was requested.** Both endpoints toggle
rather than set, so a surface holding a stale value could ask to publish
and silently unpublish instead, while the switch and the toast claimed
success — and for downloads that value also gates the download buttons
through `isDownloadAllowed()`. `ShareAccessComponent.setPublished` and
both switches on the model page now read the flag back after the write
and render that, and `setPublished(id, next)` documents that `next` is
only what the caller asked for.

A read-back that itself fails keeps the requested value and still
reports success: `GET /model/{mid}` sizes the repository through
`withLakeFSErrorHandling` and so can fail where `/model/list` (which
falls back to `0`) would not, and reporting that as a failure invited a
retry that toggled the resource straight back.

Knock-on effects: a failed publish inside the workspace no longer leaves
a false published badge on the canvas; the toast names the real outcome;
and the Settings hint text now updates on click rather than after the
round trip. That last one is load-bearing, not cosmetic — the switch
value is written optimistically so the correction is a real change,
since with one-way `[ngModel]` writing the value the field already holds
never reaches the control.

Published models are not discoverable yet: `listModels` passes
`includePublic = false` and models have no hub surface, so publishing
makes a model readable by direct URL only. Discovery arrives with the
hub PR.


<img width="1238" height="672" alt="Screenshot 2026-08-31 at 11 37
25 AM"
src="https://github.com/user-attachments/assets/5786cfca-9582-4213-a2fb-165146ee41aa";
/>
<img width="910" height="525" alt="Screenshot 2026-08-31 at 11 37 35 AM"
src="https://github.com/user-attachments/assets/a0865622-b80f-4375-b406-4a48908e3178";
/>

<img width="695" height="806" alt="Screenshot 2026-08-31 at 11 41 34 AM"
src="https://github.com/user-attachments/assets/3fa68e48-d974-4ac2-8847-e9f42cef4919";
/>
<img width="770" height="249" alt="Screenshot 2026-08-31 at 11 42 05 AM"
src="https://github.com/user-attachments/assets/31a5d4f1-7720-4356-b483-3966249dd59c";
/>

### Any related issues, documentation, discussions?

Part of #6501. Fourth in the model frontend series.

### How was this PR tested?

New tests: model publicity/downloadable/cover/owners requests in
`model.service.spec`; both toggles with a rejected-request rollback,
cover path prefixing and the no-version guard in
`model-detail.component.spec`; descriptor slot presence, the `clonable`
affordance and model delegation in `resource-registry.service.spec`; and
the clone-warning copy in `share-access.component.spec`. The
share-access publish tests moved onto `setPublished`, and the
browse-section cover specs now assert the resolved URL rather than a
concatenated one.

For the read-back above, the share-access doubles became stateful — the
workflow endpoint sets absolutely, the dataset one toggles — so a read
after a write sees the new value rather than a constant. Both surfaces
pin the stale case directly: a modal that loaded a private dataset,
published elsewhere in the meantime, must report *unpublished* after
asking to publish. Also covered on both: a landed toggle whose read-back
throws still reports success, and a failed toggle rolls the switch back.

The model page's stale case is asserted against the **rendered switch**,
not just the field, since that is where it would surface. Two details
make that assertion real rather than vacuous: the read-back is deferred
through a `Subject`, because a synchronous one collapses both writes
into a single change-detection pass, and `NgModel` pushes to the control
in a microtask, so the test flushes one before reading the DOM.

2752 tests pass across `dashboard`, `hub`, `common` and the workspace
menu/power-button specs. `tsc --noEmit` and Prettier are clean.

Manually verified: sharing a model with a second user (grant, level
change, revoke), publishing from both the share modal and the Settings
tab, the downloadable toggle as owner and as a collaborator, setting a
cover from a committed image and seeing it on the detail page and the
model card, and regression checks on dataset and workflow sharing,
publishing and covers including the workspace's in-canvas publish state.

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

Generated-by: Claude Code (Claude Opus 5)

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

With regards,
GitHub Actions via GitBox

Reply via email to