feat(marketplace): admin publish control for assessments - #8477
Open
LWS49 wants to merge 1 commit into
Open
Conversation
LWS49
commented
Jul 8, 2026
Collaborator
- add publish/remove listing endpoints (admin-gated create/destroy)
- expose canPublishToMarketplace + listing state on assessment show DTO
- add Publish/Remove to Marketplace button on the assessment header
- warn in the delete Prompt when a listed assessment is removed
- add MarketplaceAPI client, translations, and controller/FE specs
LWS49
force-pushed
the
lws49/feat-marketplace-pr2-publish
branch
from
July 8, 2026 02:48
d548294 to
a992507
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr1-foundation
branch
from
July 8, 2026 02:50
e89f6b9 to
35884a1
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr2-publish
branch
3 times, most recently
from
July 8, 2026 03:25
03ffa6a to
c630a44
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr1-foundation
branch
from
July 8, 2026 03:58
35884a1 to
833d37f
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr2-publish
branch
from
July 8, 2026 04:00
c630a44 to
a1dda4c
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr1-foundation
branch
from
July 8, 2026 04:05
833d37f to
9926c90
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr2-publish
branch
2 times, most recently
from
July 8, 2026 04:07
cbdd315 to
dd68b1c
Compare
LWS49
force-pushed
the
lws49/feat-marketplace-pr1-foundation
branch
from
July 17, 2026 08:06
9926c90 to
b34bd1d
Compare
- add publish/remove listing endpoints (admin-gated create/destroy) - expose canPublishToMarketplace + listing state on assessment show DTO - add Publish/Remove to Marketplace button on the assessment header - warn in the delete Prompt when a listed assessment is removed - add MarketplaceAPI client, translations, and controller/FE specs
LWS49
force-pushed
the
lws49/feat-marketplace-pr2-publish
branch
from
July 17, 2026 08:08
dd68b1c to
c15d911
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an admin-only control flow for publishing/removing course assessments to/from the Assessment Marketplace, surfaces marketplace state/permissions in the assessment show payload, and wires this into the assessment header UI with supporting API client, i18n strings, and specs.
Changes:
- Add admin-gated
create/destroyendpoints for an assessment’s marketplace listing and route wiring. - Expose
canPublishToMarketplace, listing state, and listing URL on the assessment show JSON + TypeScript DTO. - Add a Publish/Remove button (with confirmation prompts, toasts, and translations) plus controller/FE tests.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/controllers/course/assessment/marketplace_listings_controller_spec.rb | New controller spec coverage for publish/remove behavior and authorization. |
| spec/controllers/course/assessment/assessments_marketplace_spec.rb | New spec verifying marketplace-related fields on assessment show JSON. |
| config/routes.rb | Adds nested singular marketplace_listing resource under assessments. |
| app/controllers/course/assessment/marketplace_listings_controller.rb | New controller implementing publish/remove listing actions with admin gating. |
| app/views/course/assessment/assessments/show.json.jbuilder | Adds marketplace permission/state/url fields to assessment show DTO. |
| client/app/types/course/assessment/assessments.ts | Extends AssessmentData with marketplace permission/state/url fields. |
| client/app/api/course/Marketplace.ts | New client for publish/remove listing API calls. |
| client/app/api/course/index.js | Registers the new Marketplace API client under CourseAPI.marketplace. |
| client/app/bundles/course/marketplace/translations.ts | New react-intl message definitions for marketplace UI strings. |
| client/locales/en.json | Adds English strings for publish/remove confirmations, toasts, and delete warning. |
| client/locales/zh.json | Adds Chinese strings for publish/remove confirmations, toasts, and delete warning. |
| client/locales/ko.json | Adds Korean strings for publish/remove confirmations, toasts, and delete warning. |
| client/app/bundles/course/marketplace/components/PublishToMarketplaceButton.tsx | New publish/remove button with confirmation prompt and toasts. |
| client/app/bundles/course/marketplace/components/test/PublishToMarketplaceButton.test.tsx | New tests for publish/remove button behavior. |
| client/app/bundles/course/assessment/pages/AssessmentShow/AssessmentShowHeader.tsx | Adds marketplace publish/remove control and delete prompt warning. |
| client/app/bundles/course/assessment/pages/AssessmentShow/test/AssessmentShowHeader.test.tsx | New tests for conditional delete warning when listed. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| listing.published = true | ||
| listing.first_published_at ||= now | ||
| listing.last_published_at = now | ||
| listing.publisher ||= current_user |
Comment on lines
+80
to
+87
| <PromptText> | ||
| {t(translations.deletingThisAssessment)} | ||
| {assessment.isPublishedToMarketplace && ( | ||
| <PromptText> | ||
| {t(marketplaceTranslations.deleteWarning)} | ||
| </PromptText> | ||
| )} | ||
| </PromptText> |
Comment on lines
+31
to
+47
| const confirm = async (): Promise<void> => { | ||
| setSubmitting(true); | ||
| try { | ||
| if (listed) { | ||
| await CourseAPI.marketplace.removeListing(assessment.id); | ||
| toast.success(t(translations.removed)); | ||
| onChange(false); | ||
| } else { | ||
| await CourseAPI.marketplace.publishListing(assessment.id); | ||
| toast.success(t(translations.published)); | ||
| onChange(true); | ||
| } | ||
| setOpen(false); | ||
| } finally { | ||
| setSubmitting(false); | ||
| } | ||
| }; |
Comment on lines
+5
to
+21
| export default class MarketplaceAPI extends BaseCourseAPI { | ||
| get #urlPrefix(): string { | ||
| return `/courses/${this.courseId}/marketplace`; | ||
| } | ||
|
|
||
| publishListing(assessmentId: number): Promise<AxiosResponse> { | ||
| return this.client.post( | ||
| `/courses/${this.courseId}/assessments/${assessmentId}/marketplace_listing`, | ||
| ); | ||
| } | ||
|
|
||
| removeListing(assessmentId: number): Promise<AxiosResponse> { | ||
| return this.client.delete( | ||
| `/courses/${this.courseId}/assessments/${assessmentId}/marketplace_listing`, | ||
| ); | ||
| } | ||
| } |
Contributor
There was a problem hiding this comment.
If there are more handlers using #urlPrefix in future PRs, this can be safely ignored.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.