feat: add publication targets page#548
Conversation
There was a problem hiding this comment.
Pull request overview
Adds new repositories UI for Publication targets (and related Publications UI scaffolding) backed by a new DebArchive fetch provider, MSW mocks, and URL-param refactors for side-panel routing.
Changes:
- Adds
/repositories/publication-targetspage, components, hooks, and MSW handlers/mocks for publication targets/publications. - Introduces DebArchive-specific Axios provider (
FetchDebArchiveProvider) +useFetchDebArchiveand Vite/v1proxy handling. - Refactors page URL params usage from
profile→nameacross multiple profile pages/components.
Reviewed changes
Copilot reviewed 186 out of 188 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| vite.config.ts | Add conditional /v1 dev proxy when MSW disabled |
| src/tests/server/handlers/publicationTargets.ts | Add MSW handlers for publicationTargets CRUD + list |
| src/tests/server/handlers/index.ts | Register new MSW handlers (publications + publicationTargets) |
| src/tests/mocks/publications.ts | Add publications/mirrors/locals/publicationTargets mocks (publications feature) |
| src/tests/mocks/publication-targets.ts | Add publicationTargets/publications mocks (publication-targets feature) |
| src/tests/browser.ts | Update MSW passthrough rules to allow /v1/ traffic |
| src/templates/dashboard/SecondaryNavigation/SecondaryNavigation.module.scss | Make secondary nav sticky/full-height |
| src/providers/AppProviders.tsx | Add FetchDebArchiveProvider wrapping app |
| src/pages/dashboard/repositories/publications/PublicationsPage.tsx | Implement Publications page with URL-driven side panel |
| src/pages/dashboard/repositories/publication-targets/PublicationTargetsPage.tsx | Implement Publication targets page using feature container |
| src/pages/dashboard/repositories/publication-targets/PublicationTargetsPage.test.tsx | Add basic PublicationTargetsPage tests |
| src/pages/dashboard/profiles/wsl-profiles/WslProfilesPage.tsx | Rename page param usage from profile → name |
| src/pages/dashboard/profiles/upgrade-profiles/UpgradeProfilesPage/UpgradeProfilesPage.tsx | Rename page param usage from profile → name |
| src/pages/dashboard/profiles/security-profiles/SecurityProfilesPage/SecurityProfilesPage.tsx | Rename page param usage from profile → name |
| src/pages/dashboard/profiles/removal-profiles/RemovalProfilesPage/RemovalProfilesPage.tsx | Rename page param usage from profile → name |
| src/pages/dashboard/profiles/reboot-profiles/RebootProfilesPage/RebootProfilesPage.tsx | Rename page param usage from profile → name |
| src/pages/dashboard/profiles/package-profiles/PackageProfilesPage/PackageProfilesPage.tsx | Rename page param usage from profile → name |
| src/pages/dashboard/instances/[single]/tabs/info/ProfileLink/helpers.ts | Update routes to use name query param |
| src/libs/pageParamsManager/types.ts | Rename profile param to name in PageParams |
| src/libs/pageParamsManager/constants.ts | Add publication url param config (and retains profile) |
| src/hooks/useFetchDebArchive.ts | Add DebArchive fetch hook |
| src/features/wsl-profiles/components/WslProfilesListActions/WslProfilesListActions.tsx | Rename page param usage from profile → name |
| src/features/wsl-profiles/components/WslProfilesList/WslProfilesList.tsx | Rename page param usage from profile → name |
| src/features/wsl-profiles/components/WslProfileRemoveModal/WslProfileRemoveModal.tsx | Rename page param usage from profile → name |
| src/features/wsl-profiles/components/WslProfileEditSidePanel/components/WslProfileEditForm/WslProfileEditForm.tsx | Rename page param usage from profile → name |
| src/features/wsl-profiles/components/WslProfileAddButton/WslProfileAddButton.tsx | Rename page param usage from profile → name |
| src/features/wsl-profiles/api/useGetPageWslProfile.ts | Read WSL profile from name page param |
| src/features/upgrade-profiles/components/UpgradeProfileRemoveModal/UpgradeProfileRemoveModal.tsx | Rename page param usage from profile → name |
| src/features/upgrade-profiles/components/UpgradeProfileListActions/UpgradeProfileListActions.tsx | Rename page param usage from profile → name |
| src/features/upgrade-profiles/components/UpgradeProfileList/UpgradeProfileList.tsx | Rename page param usage from profile → name |
| src/features/upgrade-profiles/components/SingleUpgradeProfileForm/SingleUpgradeProfileForm.tsx | Rename page param usage from profile → name |
| src/features/upgrade-profiles/api/useGetPageUpgradeProfile.ts | Read upgrade profile id from name page param |
| src/features/security-profiles/hooks/useSecurityProfileForm.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/components/SecurityProfilesList/SecurityProfilesList.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/components/SecurityProfilesContainer/SecurityProfilesContainer.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/components/SecurityProfileRunFixSidePanel/SecurityProfileRunFixSidePanel.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/components/SecurityProfileListActions/SecurityProfileListActions.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/components/SecurityProfileForm/SecurityProfileForm.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/components/SecurityProfileDownloadAuditSidePanel/components/SecurityProfileDownloadAuditForm/SecurityProfileDownloadAuditForm.tsx | Rename page param usage from profile → name |
| src/features/security-profiles/api/useGetPageSecurityProfile.tsx | Read security profile id from name page param |
| src/features/scripts/components/ScriptList/ScriptList.tsx | Rename page param usage from profile → name |
| src/features/scripts/components/ScriptDetailsInfo/ScriptDetailsInfo.tsx | Rename page param usage from profile → name |
| src/features/script-profiles/components/ScriptProfilesTab/ScriptProfilesTab.tsx | Rename page param usage from profile → name |
| src/features/script-profiles/components/ScriptProfilesListActions/ScriptProfilesListActions.tsx | Rename page param usage from profile → name |
| src/features/script-profiles/components/ScriptProfilesList/ScriptProfilesList.tsx | Rename page param usage from profile → name |
| src/features/script-profiles/components/ScriptProfileForm/ScriptProfileForm.tsx | Rename page param usage from profile → name |
| src/features/script-profiles/components/AddScriptProfileButton/AddScriptProfileButton.tsx | Rename page param usage from profile → name |
| src/features/script-profiles/api/useGetPageScriptProfile.ts | Read script profile id from name page param |
| src/features/removal-profiles/components/SingleRemovalProfileForm/SingleRemovalProfileForm.tsx | Rename page param usage from profile → name |
| src/features/removal-profiles/components/RemovalProfilesEmptyState/RemovalProfilesEmptyState.tsx | Rename page param usage from profile → name |
| src/features/removal-profiles/components/RemovalProfileRemoveModal/RemovalProfileRemoveModal.tsx | Rename page param usage from profile → name |
| src/features/removal-profiles/components/RemovalProfileListActions/RemovalProfileListActions.tsx | Rename page param usage from profile → name |
| src/features/removal-profiles/components/RemovalProfileList/RemovalProfileList.tsx | Rename page param usage from profile → name |
| src/features/removal-profiles/api/useGetPageRemovalProfile.ts | Read removal profile id from name page param |
| src/features/reboot-profiles/components/RebootProfilesListActions/RebootProfilesListActions.tsx | Rename page param usage from profile → name |
| src/features/reboot-profiles/components/RebootProfilesList/RebootProfilesList.tsx | Rename page param usage from profile → name |
| src/features/reboot-profiles/components/RebootProfilesForm/RebootProfilesForm.tsx | Rename page param usage from profile → name |
| src/features/reboot-profiles/components/RebootProfilesContainer/RebootProfilesContainer.tsx | Rename page param usage from profile → name |
| src/features/reboot-profiles/components/RebootProfileRemoveModal/RebootProfileRemoveModal.tsx | Rename page param usage from profile → name |
| src/features/reboot-profiles/api/useGetPageRebootProfile.ts | Read reboot profile id from name page param |
| src/features/publications/types/index.ts | Export publications feature types |
| src/features/publications/types/Publication.ts | Add publications feature type definitions |
| src/features/publications/index.ts | Export publications feature components/helpers |
| src/features/publications/helpers.ts | Add source/publication name helper functions |
| src/features/publications/components/RepublishPublicationModal/index.ts | Barrel export |
| src/features/publications/components/RepublishPublicationModal/RepublishPublicationModal.tsx | Add republish confirmation modal |
| src/features/publications/components/RepublishPublicationModal/RepublishPublicationModal.test.tsx | Add republish modal tests |
| src/features/publications/components/RemovePublicationModal/index.ts | Barrel export |
| src/features/publications/components/RemovePublicationModal/RemovePublicationModal.tsx | Add remove confirmation modal |
| src/features/publications/components/RemovePublicationModal/RemovePublicationModal.test.tsx | Add remove modal tests |
| src/features/publications/components/PublicationsListActions/index.ts | Barrel export |
| src/features/publications/components/PublicationsListActions/PublicationsListActions.tsx | Add per-row actions menu (view/republish/remove) |
| src/features/publications/components/PublicationsListActions/PublicationsListActions.test.tsx | Add actions menu tests |
| src/features/publications/components/PublicationsList/index.ts | Barrel export |
| src/features/publications/components/PublicationsList/PublicationsList.tsx | Add publications table |
| src/features/publications/components/PublicationsList/PublicationsList.test.tsx | Add publications table tests |
| src/features/publications/components/PublicationsHeader/index.ts | Barrel export |
| src/features/publications/components/PublicationsHeader/PublicationsHeader.tsx | Add publications search header |
| src/features/publications/components/PublicationsHeader/PublicationsHeader.test.tsx | Add header tests |
| src/features/publications/components/PublicationsContainer/index.ts | Barrel export |
| src/features/publications/components/PublicationsContainer/PublicationsContainer.tsx | Add publications container (loading + empty states + pagination) |
| src/features/publications/components/PublicationsContainer/PublicationsContainer.test.tsx | Add container tests |
| src/features/publications/components/PublicationDetailsSidePanel/index.ts | Barrel export |
| src/features/publications/components/PublicationDetailsSidePanel/PublicationDetailsSidePanel.tsx | Add URL-driven publication details side panel |
| src/features/publications/components/PublicationDetails/index.ts | Barrel export |
| src/features/publications/components/PublicationDetails/PublicationDetails.tsx | Add publication details view + actions |
| src/features/publications/components/PublicationDetails/PublicationDetails.test.tsx | Add details tests |
| src/features/publications/components/NoPublicationsTargetEmptyState/index.ts | Barrel export |
| src/features/publications/components/NoPublicationsTargetEmptyState/NoPublicationTargetEmptyState.tsx | Add empty state when no targets exist |
| src/features/publications/components/NoPublicationsTargetEmptyState/NoPublicationTargetEmptyState.test.tsx | Add empty state tests |
| src/features/publications/components/NoPublicationsEmptyState/index.ts | Barrel export |
| src/features/publications/components/NoPublicationsEmptyState/constants.ts | Add publications docs URL constant |
| src/features/publications/components/NoPublicationsEmptyState/NoPublicationsEmptyState.tsx | Add empty state when no publications exist |
| src/features/publications/components/NoPublicationsEmptyState/NoPublicationsEmptyState.test.tsx | Add empty state tests |
| src/features/publications/components/AddPublicationForm/types.ts | Add add-publication form value types |
| src/features/publications/components/AddPublicationForm/index.ts | Barrel export |
| src/features/publications/components/AddPublicationForm/helpers.ts | Add form validation + payload builder |
| src/features/publications/components/AddPublicationForm/constants.ts | Add form constants/initial values/help text |
| src/features/publications/components/AddPublicationForm/AddPublicationForm.module.scss | Add form styles |
| src/features/publications/components/AddPublicationForm/AddPublicationForm.tsx | Add full add-publication side-panel form |
| src/features/publications/components/AddPublicationButton/index.ts | Barrel export |
| src/features/publications/components/AddPublicationButton/AddPublicationButton.tsx | Add “Add publication” button opening side panel |
| src/features/publications/components/AddPublicationButton/AddPublicationButton.test.tsx | Add button tests |
| src/features/publications/api/useUpdatePublication.ts | Add update publication mutation |
| src/features/publications/api/usePublishPublication.ts | Add publish/republish mutation |
| src/features/publications/api/useGetPublications.ts | Add list + client-side search/pagination hook |
| src/features/publications/api/useGetPublicationTargets.ts | Add publication targets list hook (for publications feature) |
| src/features/publications/api/useGetPublication.ts | Add single publication fetch hook |
| src/features/publications/api/useGetPagePublication.ts | Add URL-param-driven publication fetch hook |
| src/features/publications/api/useGetMirrors.ts | Add mirrors list hook |
| src/features/publications/api/useGetLocals.ts | Add locals list hook |
| src/features/publications/api/useDeletePublication.ts | Add delete publication mutation |
| src/features/publications/api/useCreatePublication.ts | Add create publication mutation |
| src/features/publication-targets/types/index.ts | Export publication-targets feature types |
| src/features/publication-targets/types/PublicationTarget.ts | Re-export openapi publication target types |
| src/features/publication-targets/types/Publication.ts | Re-export publication type |
| src/features/publication-targets/index.ts | Export publication-targets feature public API |
| src/features/publication-targets/components/TargetDetails/index.ts | Barrel export |
| src/features/publication-targets/components/TargetDetails/TargetDetails.tsx | Add target details side-panel content |
| src/features/publication-targets/components/TargetDetails/TargetDetails.test.tsx | Add target details tests |
| src/features/publication-targets/components/RemoveTargetForm/index.ts | Barrel export |
| src/features/publication-targets/components/RemoveTargetForm/RemoveTargetModal.tsx | Add remove target confirmation modal |
| src/features/publication-targets/components/RemoveTargetForm/RemoveTargetForm.test.tsx | Add remove target tests |
| src/features/publication-targets/components/PublicationsTable/PublicationsTable.tsx | Add “Used In” publications table (side panel) |
| src/features/publication-targets/components/PublicationsTable/PublicationsTable.test.tsx | Add publications table tests |
| src/features/publication-targets/components/PublicationsTable/PublicationLink/PublicationLink.tsx | Add publication link component |
| src/features/publication-targets/components/PublicationsTable/MirrorLink/MirrorLink.tsx | Add mirror link component |
| src/features/publication-targets/components/PublicationTargetListActions/index.ts | Barrel export |
| src/features/publication-targets/components/PublicationTargetListActions/PublicationTargetListActions.tsx | Add per-target actions menu |
| src/features/publication-targets/components/PublicationTargetListActions/PublicationTargetListActions.test.tsx | Add actions menu tests |
| src/features/publication-targets/components/PublicationTargetList/index.ts | Barrel export |
| src/features/publication-targets/components/PublicationTargetList/PublicationTargetList.tsx | Add publication targets list table |
| src/features/publication-targets/components/PublicationTargetList/PublicationTargetList.test.tsx | Add list tests |
| src/features/publication-targets/components/PublicationTargetContainer/index.ts | Barrel export |
| src/features/publication-targets/components/PublicationTargetContainer/PublicationTargetContainer.tsx | Add container (loading + empty state + list) |
| src/features/publication-targets/components/PublicationTargetContainer/PublicationTargetContainer.test.tsx | Add container tests |
| src/features/publication-targets/components/PublicationTargetAddButton/index.ts | Barrel export |
| src/features/publication-targets/components/PublicationTargetAddButton/PublicationTargetAddButton.tsx | Add “Add publication target” button |
| src/features/publication-targets/components/PublicationTargetAddButton/PublicationTargetAddButton.test.tsx | Add button tests |
| src/features/publication-targets/components/EditTargetForm/index.ts | Barrel export |
| src/features/publication-targets/components/EditTargetForm/EditTargetForm.tsx | Add edit target form |
| src/features/publication-targets/components/EditTargetForm/EditTargetForm.test.tsx | Add edit form tests |
| src/features/publication-targets/components/AddPublicationTargetForm/index.ts | Barrel export |
| src/features/publication-targets/components/AddPublicationTargetForm/constants.ts | Add create target initial values |
| src/features/publication-targets/components/AddPublicationTargetForm/AddPublicationTargetForm.tsx | Add create target form |
| src/features/publication-targets/components/AddPublicationTargetForm/AddPublicationTargetForm.test.tsx | Add create form tests |
| src/features/publication-targets/api/useRemovePublicationTarget.ts | Add remove target mutation |
| src/features/publication-targets/api/useGetPublicationsByTarget.ts | Add publications-by-target query |
| src/features/publication-targets/api/useGetPublicationTargets.ts | Add targets list query |
| src/features/publication-targets/api/useEditPublicationTarget.ts | Add edit target mutation |
| src/features/publication-targets/api/useCreatePublicationTarget.ts | Add create target mutation |
| src/features/publication-targets/api/index.ts | Barrel export for API hooks |
| src/features/package-profiles/components/PackageProfilesEmptyState/PackageProfilesEmptyState.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/components/PackageProfileRemoveModal/PackageProfileRemoveModal.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/components/PackageProfileListActions/PackageProfileListActions.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/components/PackageProfileList/PackageProfileList.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/components/PackageProfileEditSidePanel/components/PackageProfileEditForm/PackageProfileEditForm.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/components/PackageProfileDuplicateSidePanel/components/PackageProfileDuplicateForm/PackageProfileDuplicateForm.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/components/PackageProfileAddSidePanel/PackageProfileAddSidePanel.tsx | Rename page param usage from profile → name |
| src/features/package-profiles/api/useGetPagePackageProfile.ts | Read package profile from name page param |
| src/constants.ts | Add API_URL_DEBARCHIVE constant |
| src/components/layout/InfoGrid/InfoGrid.tsx | Add dense prop and update class handling |
| src/components/layout/InfoGrid/InfoGrid.module.scss | Add dense grid spacing class |
| src/components/layout/Blocks/Item/Item.tsx | Allow custom title/container classNames |
| src/components/form/ReadOnlyField/index.ts | Barrel export |
| src/components/form/ReadOnlyField/ReadOnlyField.tsx | Add read-only “locked” field component |
| src/components/form/ReadOnlyField/ReadOnlyField.module.scss | Add styles for locked/read-only field |
| src/api/fetchDebArchive.tsx | Add DebArchive Axios provider/context |
| package.json | Add @canonical/landscape-openapi and change react-components version |
| pnpm-lock.yaml | Lockfile updates for new deps/versions |
| AGENTS.md | Documentation updates (currently conflict markers present) |
| .github/prompts/explore-plan.prompt.md | Add feature planning prompt |
| .github/prompts/architect.prompt.md | Add Architect persona prompt |
| .github/feature-plans/publication-links-per-target.md | Add feature plan doc |
| .github/feature-plans/debarchive-seed-data.md | Add debarchive seeding plan doc |
| .github/agents/tester.agent.md | Add tester agent instructions |
| .github/agents/prompt-engineer.agent.md | Add prompt engineer agent instructions |
| .github/agents/implementer.agent.md | Add implementer agent instructions |
| .github/agents/debugger.agent.md | Add debugger agent instructions |
| .github/agents/architect.agent.md | Add architect agent instructions |
| .changeset/silver-pots-rush.md | Add changeset entry (publication targets page) |
| .changeset/bold-loops-retire.md | Add changeset entry with more detail |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <<<<<<< HEAD | ||
| ## Environment Setup | ||
|
|
||
| Copy `.env.local.example` to `.env.local` and fill in values for your local Landscape instance. Required variables include `VITE_API_URL`, `VITE_API_URL_OLD`, and `VITE_ROOT_PATH`. Set `VITE_MSW_ENABLED=true` to use Mock Service Worker for offline development. See `.env.local.example` for the full list. | ||
|
|
||
| Node.js ≥24 is required (`engines` in `package.json`). | ||
| ======= | ||
| ## Agent Failure Protocol | ||
|
|
||
| **Stop and ask the user instead of retrying** when: | ||
|
|
||
| - A file write (overwrite, truncation, replacement) appears to succeed (exit 0) but the file content does not change on re-read. This indicates VS Code workspace locking or a tool limitation — retrying the same approach will not help. | ||
| - Two different tool strategies for the same operation both fail to produce the expected result. | ||
| - A `replace_string_in_file` cannot find a unique anchor because the target content is duplicated or spans more than ~30 lines. | ||
|
|
||
| In these cases: describe the exact manual action needed (file path, line numbers, what to delete/change) and wait for the user to confirm it is done before continuing. | ||
| >>>>>>> 21c758433 (update AGENTS.md, feature plans, and editTargetForm) |
There was a problem hiding this comment.
AGENTS.md contains unresolved git merge conflict markers (<<<<<<<, =======, >>>>>>>). This will break rendering/reading of the file and indicates an incomplete merge. Resolve the conflict and keep only the intended content (Environment Setup + Agent Failure Protocol, or whichever is correct).
| { | ||
| urlParam: "profile", | ||
| shouldResetPage: false, | ||
| defaultValue: DEFAULT_EMPTY_STRING, | ||
| }, | ||
| { | ||
| urlParam: "publication", | ||
| shouldResetPage: false, | ||
| defaultValue: DEFAULT_EMPTY_STRING, | ||
| }, |
There was a problem hiding this comment.
PARAMS_CONFIG still declares a urlParam: "profile", but PageParams no longer includes profile (it was renamed to name). As written, this should fail TypeScript (and will also keep parsing/writing the wrong URL param at runtime). Update the config to use name, and ensure the newly added publication param is also represented in PageParams if it’s meant to be supported.
| return { | ||
| publicationId, | ||
| body: { | ||
| publicationTarget: prependResourcePrefix( | ||
| values.publication_target, | ||
| "publicationTargets/", | ||
| ), | ||
| mirror: prependResourcePrefix(values.source, "mirrors/"), | ||
| distribution: values.uploader_distribution.trim() || undefined, | ||
| component: components[0], | ||
| label: values.prefix.trim() || undefined, | ||
| architectures: architectures.length > 0 ? architectures : undefined, | ||
| acquireByHash: values.hash_indexing, | ||
| notAutomatic: !values.automatic_installation, | ||
| butAutomaticUpgrades: values.automatic_upgrades, | ||
| skipBz2: values.skip_bz2, | ||
| skipContents: values.skip_content_indexing, | ||
| gpgKey: values.preserve_mirror_signing_key | ||
| ? undefined | ||
| : { | ||
| armor: values.mirror_signing_key.trim(), | ||
| }, | ||
| }, |
There was a problem hiding this comment.
getPublicationPayload builds a PublicationWritable body with a mirror field, but PublicationWritable defines the field as source. This will either fail compilation (excess property + missing required source) or send the wrong payload shape to the API. Align the payload keys with PublicationWritable/API (e.g., use source and ensure component is actually part of the writable type if required).
There was a problem hiding this comment.
resolve in feature/publications-page branch
| { | ||
| accessor: "mirror", | ||
| Header: "mirror", | ||
| Cell: ({ row: { original } }: CellProps<Publication>) => ( | ||
| <StaticLink to="/">{original.mirror}</StaticLink> | ||
| ), | ||
| }, | ||
| { | ||
| accessor: "publicationTarget", | ||
| Header: "publication target", | ||
| Cell: ({ row: { original } }: CellProps<Publication>) => ( | ||
| <StaticLink to="/">{original.publicationTarget}</StaticLink> | ||
| ), | ||
| }, | ||
| { | ||
| accessor: "distribution", | ||
| Header: "distribution", | ||
| Cell: ({ row: { original } }: CellProps<Publication>) => ( | ||
| <>{original.distribution}</> | ||
| ), | ||
| }, | ||
| { | ||
| accessor: "component", | ||
| Header: "component", | ||
| Cell: ({ row: { original } }: CellProps<Publication>) => ( | ||
| <>{original.component}</> | ||
| ), | ||
| }, |
There was a problem hiding this comment.
This table renders original.mirror and original.component, but the Publication type used here defines source (not mirror) and does not include component. This is likely a type/API mismatch that will either fail TypeScript or render undefined in the UI. Decide on the canonical Publication shape (preferably from the OpenAPI types) and update the component/mocks accordingly (e.g., display source and/or derive a friendly name via getSourceName).
| specifier: 4.2.0 | ||
| version: 4.2.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(formik@2.4.9(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vanilla-framework@4.46.0(sass@1.99.0)) |
There was a problem hiding this comment.
pnpm-lock.yaml is inconsistent with package.json: the lockfile still pins @canonical/react-components to 4.2.0 in the importer section while package.json now requires 4.0.0. This can cause non-reproducible installs/CI failures. Regenerate the lockfile (or otherwise update it) so the importer dependency matches the actual package.json version.
| specifier: 4.2.0 | |
| version: 4.2.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(formik@2.4.9(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vanilla-framework@4.46.0(sass@1.99.0)) | |
| specifier: 4.0.0 | |
| version: 4.0.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(formik@2.4.9(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vanilla-framework@4.46.0(sass@1.99.0)) |
| <ResponsiveTable | ||
| columns={columns} | ||
| data={publications} | ||
| emptyMsg={`No profiles found with the search: "${search}"`} | ||
| /> |
There was a problem hiding this comment.
emptyMsg says "No profiles found..." but this component is for publications. This will show the wrong empty state message to users; update it to reference publications instead of profiles.
| "landscape-ui": minor | ||
| --- | ||
|
|
||
| Add /publications-target page |
There was a problem hiding this comment.
This changeset description says "Add /publications-target page", but the actual route in this PR is /repositories/publication-targets (plural + under repositories). Update the changeset text to match the real feature path so the generated changelog is accurate.
| Add /publications-target page | |
| Add /repositories/publication-targets page |
| }) => ( | ||
| <div className={classes.field}> | ||
| <label>{required ? "* " : ""} {label}</label> | ||
| <Tooltip position="btm-left" className={classes.container} message={tooltipMessage} followMouse> | ||
| <div className={classes.locked}> | ||
| <span>{value}</span> | ||
| <Icon name="lock-locked" /> | ||
| </div> | ||
| </Tooltip> | ||
| </div> | ||
| ); | ||
|
|
There was a problem hiding this comment.
ReadOnlyField always renders a Tooltip even when tooltipMessage is undefined. In this codebase, Tooltip is typically provided a non-empty message; passing undefined may cause runtime warnings or an empty tooltip. Consider rendering the tooltip wrapper only when tooltipMessage is set, and use a non-label element (e.g., <span>) if this isn’t labeling an actual form control for accessibility.
| }) => ( | |
| <div className={classes.field}> | |
| <label>{required ? "* " : ""} {label}</label> | |
| <Tooltip position="btm-left" className={classes.container} message={tooltipMessage} followMouse> | |
| <div className={classes.locked}> | |
| <span>{value}</span> | |
| <Icon name="lock-locked" /> | |
| </div> | |
| </Tooltip> | |
| </div> | |
| ); | |
| }) => { | |
| const lockedContent = ( | |
| <div className={classes.locked}> | |
| <span>{value}</span> | |
| <Icon name="lock-locked" /> | |
| </div> | |
| ); | |
| return ( | |
| <div className={classes.field}> | |
| <span>{required ? "* " : ""} {label}</span> | |
| {tooltipMessage ? ( | |
| <Tooltip | |
| position="btm-left" | |
| className={classes.container} | |
| message={tooltipMessage} | |
| followMouse | |
| > | |
| {lockedContent} | |
| </Tooltip> | |
| ) : ( | |
| lockedContent | |
| )} | |
| </div> | |
| ); | |
| }; |
There was a problem hiding this comment.
Address this in a different branch or upstream component contribution
…n targets page, MSWs for publication targets and child publications
…dscape-go backend. Left out changes involving type and endpoint generation until we decide on a tool for that (orval vs hey-api)
…t directly at openapi package; updated tests
…blication info in a side panel on /publications
…once those branches are merged in Remove count link from target list, link to publication with query from list updated openapi package, used filter for getting publications by target ID consolidate pageParams to use name instead of (profile, publication, mirror). Add test for page Use ReadOnlyField in EditTargetForm use ConfirmationModal prop to solve z-index issue from side panel instead of custom css class update success notifications Add url params for publication targets and linking other resources check out changes from /feature/publications-page fix page params, resolve copilot comments, remove extra changelog remove modal links open in new tab check out new changes from feature/publications-page, confirm that URL params work across page add URL param handling for "add publication target" form and test coverage standardize side panel size dense prop / styling for Blocks header fix pagination in remove target modal url queries for edit target form, style fixes remove comment
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
ethanashaw
left a comment
There was a problem hiding this comment.
Looks good, just a few simple changes
There was a problem hiding this comment.
I couldn't repro this, could you check with the new commit if you still see it?
There was a problem hiding this comment.
Sure, this is the behavior I'm seeing:
Screencast.from.2026-04-27.15-10-35.webm
Although after a quick glance at the code, nothing seems off, so I'm not sure why this is happening. It might just be a quirk with the table library
Co-authored-by: Copilot <copilot@github.com>

Summary
Created new page at /repositories/publication-targets with UI matching the design file. Since no API endpoints exist yet all /publicationTargets and /publications endpoints should be mocked. PublicationsTable will need to be updated with links to individual publications and sources once those pages are added. Leaving as a draft so we can decide whether to merge in to deb-archive now or wait for those changes.
Release Impact
According to the Landscape Server Release Cycle, this change will target the following release cycle:
dev/main(Beta)Checklist
pnpm changesetand committed the resulting.mdfile.scripts/).Versioning Reminder
Important
This repository now uses CalVer ($YY.0M.Point.Patch$ ).
Please ensure your changeset description is clear, as it will be automatically added to the
CHANGELOG.mdupon merging tomain.