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
