Skip to content

feat(msm): bring Multi-site Manager to main - #1341

Open
keepthebyte wants to merge 5 commits into
adobe:mainfrom
keepthebyte:msm-to-main
Open

keepthebyte wants to merge 5 commits into
adobe:mainfrom
keepthebyte:msm-to-main

Conversation

@keepthebyte

Copy link
Copy Markdown

Brings the Multi-site Manager panel to main, so it stops living on a branch.

MSM has been on the msm branch
since #871, which merged into that branch rather than into main. Everything
in it 404s on production today, so the feature is unreachable: the prepare
config row that should open it finds no OOTB entry, path stays undefined,
and the dialog renders an iframe pointing at the page base — the right title
over an empty body.

What this adds

file
blocks/edit/da-prepare/actions/msm/msm.js the panel — Preview, Publish, Cancel inheritance, Sync to satellite, Resume inheritance
…/msm/helpers/config.js resolves a site's role from the org msm sheet
…/msm/helpers/utils.js the per-action calls
…/msm/msm.css, …/msm/README.md styles and docs
blocks/edit/da-prepare/da-prepare.js registers it in the classic prepare menu (+6)
blocks/canvas/editor-utils/prepare-menu.js registers it in the canvas prepare menu (+6)

The canvas registration is the part #871 never had — it predates the canvas
entirely, and the canvas keeps its own OOTB_ACTIONS. Since /edit now
redirects to /canvas, without it the panel would still be unreachable on
main. Both menus use the same OOTB_ACTIONS + render shape and the canvas
already imports every other action from ../../edit/da-prepare/actions/, so
it is the same one-entry wiring. optional: true, so it only appears for orgs
that opt in through their prepare config, exactly as in the classic menu.

Tests

test/unit/…/msm/ — 73 tests across the panel, its config resolver and its
action helpers.

They needed one harness fix, which is the only change here to code that came
off the branch. The suite predates fetchDaConfigs moving from a direct
daFetch of ${DA_ORIGIN}/config… to the nx2 config API. Its window.fetch
mock already answers /config/ correctly, but getNx2Api() had no fixture to
resolve, so all 17 tests downstream of getSatellites failed. Fixed by using
the harness every other da-prepare test already uses:

setNx('/test/fixtures/nx', { hostname: 'example.com' });

No production code changed for that — the runtime was never broken, only
the mock. The test file also picked up the current eslint config, which has
tightened since the branch was written.

73 MSM tests pass
full suite: 157 files, 2307 passed, 0 failed, 4 skipped
npm run lint: clean

Verified against real content

Exercised on the branch preview with production IMS and production DA, on an
org with a real five-tier msm sheet
(keepthebyte: global → eu → {ie, gb, de, ch}, global → apac → sg):

  • the action picker offers all five actions, grouped Inherited sites /
    Custom sites as the docs describe;
  • the base view lists the satellites resolved live from the org config, and
    picked up a newly added one without a reload;
  • resolveConfig was run against that org's sheet for all eight sites — each
    resolves to the expected base/satellite role.

Note for reviewers

resolveConfig decides between the base/satellite shape and the legacy
single-column shape with rows[0].base !== undefined — row 0 only. That makes
the first row of an org's msm sheet load-bearing in a way nothing in the
sheet signals; a blank in that cell silently switches the whole sheet to the
other shape. Left as-is here since it is existing behaviour and out of scope,
but it might deserve a follow-up.

ravuthu and others added 5 commits April 8, 2026 08:52
* msm implementation

* Satellite site can control the sync features and inheritance

* renamed global publish to msm

* read msm mapping from Org config and preview/publish the page from base site to the satellite upon resume inheritance action

* Show a link to edit the page on custom sites

* readme added

* moved the shared file inside msm as the da-title is not using it anymore

* moved the utils methods to helpers folder

* msm unit tests
MSM is registered in blocks/edit/da-prepare/da-prepare.js only. The canvas keeps
its own OOTB_ACTIONS, so a prepare config row with 'Multi-site Manager' creates a
menu entry whose OOTB lookup misses; path stays undefined and the dialog renders
an iframe pointing at the page base:

  iframeOrigin https://<host>, iframePath /canvas, no query, body length 0

Since /edit now redirects to /canvas, this is the only reachable entry point.

msm.js reads org, site and path off details, all of which the canvas supplies,
and every other action here is already imported from ../../edit/da-prepare/actions/.
The MSM suite was written before `fetchDaConfigs` moved from a direct
`daFetch` of `${DA_ORIGIN}/config…` to the nx2 config API. Its `window.fetch`
mock already answers `/config/` correctly, but `getNx2Api()` had no fixture to
resolve, so every test that loaded an org config failed — 17 of 73, all of them
downstream of `getSatellites`.

The fix is the harness every other da-prepare test already uses:
`setNx('/test/fixtures/nx', { hostname: 'example.com' })`. No production code
changed, which is the point — the runtime was never broken, only the mock.

Also brings the test file up to the current eslint config, which has tightened
since the branch was written: two multi-statement arrow bodies expanded, and
one object literal inlined then split to stay under max-len.

73 MSM tests pass; full suite 2307 passed, 0 failed, 4 skipped; `npm run lint`
clean.
@mhaack

mhaack commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

msm.js:234-253 and :289-299 — after deleteOverride succeeds, the follow-up previewSatellite/publishSatellite results aren't checked. If AEM preview/publish fails post-delete, the UI still reports STATUS.success and clears hasOverride — satellite ends up with no override and no synced content, shown as green.

Fix: fold the preview/publish result into the error check instead of only gating on deleteOverride. Same issue in both places (base reset and satellite resume-inheritance).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants