From 390e68c29b77c55c1af8f2e4256c72e93bac1c79 Mon Sep 17 00:00:00 2001
From: Addy Pathania <89087450+sc-addypathania@users.noreply.github.com>
Date: Tue, 28 May 2024 10:14:49 -0400
Subject: [PATCH] [Editing Integration] Add `editMode` to `/editing/config`
endpoint response with configurable integration option (#1803)
* add flag to disbale metadata for editmode
* update changelog
* refactor unit tests
* update yarn.lock
* rename new config option, update uprade guide
* update upgrade guide
* Update docs/upgrades/unreleased.md
Co-authored-by: Illia Kovalenko <23364749+illiakovalenko@users.noreply.github.com>
---------
Co-authored-by: Illia Kovalenko <23364749+illiakovalenko@users.noreply.github.com>
---
CHANGELOG.md | 3 +-
docs/upgrades/unreleased.md | 13 +++++-
.../editing/editing-config-middleware.test.ts | 46 +++++++++++--------
.../src/editing/editing-config-middleware.ts | 10 ++++
4 files changed, 52 insertions(+), 20 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8b74f429c..110dce97e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,12 +23,13 @@ Our versioning strategy is as follows:
### 🛠Breaking Change
-* Editing Integration Support: ([#1776](https://github.com/Sitecore/jss/pull/1776))([#1792](https://github.com/Sitecore/jss/pull/1792))([#1773](https://github.com/Sitecore/jss/pull/1773))([#1797](https://github.com/Sitecore/jss/pull/1797))([#1800](https://github.com/Sitecore/jss/pull/1800))
+* Editing Integration Support: ([#1776](https://github.com/Sitecore/jss/pull/1776))([#1792](https://github.com/Sitecore/jss/pull/1792))([#1773](https://github.com/Sitecore/jss/pull/1773))([#1797](https://github.com/Sitecore/jss/pull/1797))([#1800](https://github.com/Sitecore/jss/pull/1800)) ([#1803](https://github.com/Sitecore/jss/pull/1803))
* `[sitecore-jss-react]` Introduces `PlaceholderMetadata` component which supports the hydration of chromes on Pages by rendering the components and placeholders with required metadata.
* `[sitecore-jss]` Chromes are hydrated based on the basis of new `editMode` property derived from LayoutData, which is defined as an enum consisting of `metadata` and `chromes`.
* `ComponentConsumerProps` is removed. You might need to reuse _WithSitecoreContextProps_ type.
* `[sitecore-jss-react]` `[sitecore-jss-nextjs]` Introduce FieldMetadata component and functionality to render it when metadata field property is provided in the field's layout data. In such case the field component is wrapped with metadata markup to enable chromes hydration when editing in pages. Ability to render metadata has been added to the field rendering components for react and nextjs.
* `[sitecore-jss-react]` Introduced `EditingScripts` component to render clientScripts / clientData in editing.
+ * `[sitecore-jss-nextjs]` `[template/nextjs-xmlcoud]` Add editMode to /editing/config endpoint response with configurable integration option.
## 22.0.0
diff --git a/docs/upgrades/unreleased.md b/docs/upgrades/unreleased.md
index 7fb590ef62..6a58073502 100644
--- a/docs/upgrades/unreleased.md
+++ b/docs/upgrades/unreleased.md
@@ -51,10 +51,21 @@
```
import { EditingScripts } from '@sitecore-jss/sitecore-jss-nextjs';
...
- const Scripts = (): JSX.Element | null => {
+ const Scripts = (): JSX.Element | null => (
<>
...
>
);
```
+
+* We have introduced a new configuration option, `pagesEditMode`, in the `\src\pages\api\editing\config.ts` file to support the new editing metadata architecture for Pages (XMCloud). This option allows you to specify the editing mode used by Pages. It is set to `metadata` by default. However, if you are not ready to use a new integration and continue using the existing architecture, you can explicitly set the `pagesEditMode` to `chromes`.
+
+ ```
+ import { EditMode } from '@sitecore-jss/sitecore-jss/layout';
+
+ const handler = new EditingConfigMiddleware({
+ ...
+ pagesEditMode: EditMode.Chromes,
+ }).getHandler();
+ ```
diff --git a/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.test.ts b/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.test.ts
index 1372b5c3ac..acd8a8446c 100644
--- a/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.test.ts
+++ b/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.test.ts
@@ -4,6 +4,7 @@ import { spy } from 'sinon';
import { expect } from 'chai';
import { EditingConfigMiddleware } from './editing-config-middleware';
import { QUERY_PARAM_EDITING_SECRET } from './constants';
+import { EditMode } from '@sitecore-jss/sitecore-jss/layout';
type Query = {
[key: string]: string;
@@ -45,10 +46,18 @@ componentsMap.set('TestComponentOne', {});
componentsMap.set('TestComponentTwo', {});
const metadata = { packages: { testPackageOne: '0.1.1' } };
-const expectedResult = {
+const expectedResultWithChromes = {
components: ['TestComponentOne', 'TestComponentTwo'],
packages: { testPackageOne: '0.1.1' },
+ editMode: 'chromes',
};
+
+const expectedResultWithMetadata = {
+ components: ['TestComponentOne', 'TestComponentTwo'],
+ packages: { testPackageOne: '0.1.1' },
+ editMode: 'metadata',
+};
+
const expectedResultForbidden = { message: 'Missing or invalid editing secret' };
describe('EditingConfigMiddleware', () => {
@@ -111,14 +120,17 @@ describe('EditingConfigMiddleware', () => {
expect(res.json).to.have.been.calledWith(expectedResultForbidden);
});
- it('should respond with 200 and return config data with components array as argument', async () => {
+ const testEditingConfig = async (
+ components: string[] | Map,
+ expectedResult,
+ pagesEditMode?: EditMode
+ ) => {
const key = 'wrongkey';
const query = { key } as Query;
query[QUERY_PARAM_EDITING_SECRET] = secret;
const req = mockRequest('GET', query);
const res = mockResponse();
-
- const middleware = new EditingConfigMiddleware({ components: componentsArray, metadata });
+ const middleware = new EditingConfigMiddleware({ components, metadata, pagesEditMode });
const handler = middleware.getHandler();
await handler(req, res);
@@ -127,23 +139,21 @@ describe('EditingConfigMiddleware', () => {
expect(res.status).to.have.been.calledWith(200);
expect(res.json).to.have.been.calledOnce;
expect(res.json).to.have.been.calledWith(expectedResult);
- });
+ };
- it('should respond with 200 and return config data with components map as argument', async () => {
- const key = 'wrongkey';
- const query = { key } as Query;
- query[QUERY_PARAM_EDITING_SECRET] = secret;
- const req = mockRequest('GET', query);
- const res = mockResponse();
+ it('should respond with 200 and return config data with components array as argument and editMode as chromes', async () => {
+ await testEditingConfig(componentsArray, expectedResultWithChromes, EditMode.Chromes);
+ });
- const middleware = new EditingConfigMiddleware({ components: componentsMap, metadata });
- const handler = middleware.getHandler();
+ it('should respond with 200 and return config data with components map as argument and editMode as chromes', async () => {
+ await testEditingConfig(componentsMap, expectedResultWithChromes, EditMode.Chromes);
+ });
- await handler(req, res);
+ it('should respond with 200 and return config data with components array as argument and editMode as metadata', async () => {
+ await testEditingConfig(componentsArray, expectedResultWithMetadata);
+ });
- expect(res.status).to.have.been.calledOnce;
- expect(res.status).to.have.been.calledWith(200);
- expect(res.json).to.have.been.calledOnce;
- expect(res.json).to.have.been.calledWith(expectedResult);
+ it('should respond with 200 and return config data with components map as argument and editMode as metadata', async () => {
+ await testEditingConfig(componentsMap, expectedResultWithMetadata);
});
});
diff --git a/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.ts b/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.ts
index 2cefa06506..7be123f5e9 100644
--- a/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.ts
+++ b/packages/sitecore-jss-nextjs/src/editing/editing-config-middleware.ts
@@ -2,6 +2,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
import { EDITING_ALLOWED_ORIGINS, QUERY_PARAM_EDITING_SECRET } from './constants';
import { getJssEditingSecret } from '../utils/utils';
import { debug } from '@sitecore-jss/sitecore-jss';
+import { EditMode } from '@sitecore-jss/sitecore-jss/layout';
import { Metadata } from '@sitecore-jss/sitecore-jss-dev-tools';
import { enforceCors } from '@sitecore-jss/sitecore-jss/utils';
@@ -14,6 +15,12 @@ export type EditingConfigMiddlewareConfig = {
* Application metadata
*/
metadata: Metadata;
+ /**
+ * Determines which editing mode should be used by Pages.
+ * Can be either 'chromes' or 'metadata'.
+ * By default its 'metadata'
+ */
+ pagesEditMode?: EditMode;
};
/**
@@ -56,9 +63,12 @@ export class EditingConfigMiddleware {
? this.config.components
: Array.from(this.config.components.keys());
+ const editMode = this.config.pagesEditMode || EditMode.Metadata;
+
return res.status(200).json({
components,
packages: this.config.metadata.packages,
+ editMode,
});
};
}