Skip to content

Commit

Permalink
[Angular] XM Cloud Forms support (#1951)
Browse files Browse the repository at this point in the history
* [Angular] XM Cloud Forms support

* Update

* Added test utils

* Update Migration guide

* Updated tsdoc

* Don't render errors, orange box when in non editing mode
  • Loading branch information
illiakovalenko authored Oct 22, 2024
1 parent 1adfe83 commit a0d83f1
Show file tree
Hide file tree
Showing 23 changed files with 1,096 additions and 191 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ Our versioning strategy is as follows:
- `scRouterLinkEmptyFieldEditingTemplate` for _scRouterLink_
- `scTextEmptyFieldEditingTemplate` for _scText_
* `[sitecore-jss-angular]` `[templates/angular-xmcloud]` Render clientScripts / clientData. The new `sc-editing-scripts` component is exposed from `sitecore-jss-angular` package and required to be rendered on the page to enable Metadata Edit mode. ([#1924](https://github.com/Sitecore/jss/pull/1924))([#1948](https://github.com/Sitecore/jss/pull/1948))
* `[sitecore-jss-angular]` `[templates/angular-xmcloud]` XM Cloud Forms support ([#1951](https://github.com/Sitecore/jss/pull/1951)):
* New "Form" component is introduced in the sitecore-jss-angular package.
* The Form component is declared in the Angular sample app.
* Introduced plugins technique for component factory generation.
* `[sitecore-jss]` GenericFieldValue model is updated to accept Date type ([#1916](https://github.com/Sitecore/jss/pull/1916))
* `[template/node-xmcloud-proxy]` `[sitecore-jss-proxy]` Introduced /api/healthz endpoint ([#1928](https://github.com/Sitecore/jss/pull/1928))
* `[sitecore-jss]` `[sitecore-jss-angular]` Render field metdata chromes in editMode metadata - in edit mode metadata in Pages, angular package field directives will render wrapping `code` elements with field metadata required for editing; ([#1926](https://github.com/Sitecore/jss/pull/1926))
Expand Down
34 changes: 34 additions & 0 deletions docs/upgrades/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,40 @@ If you plan to use the Angular SDK with XMCloud, you will need to perform next s
<sc-editing-scripts></sc-editing-scripts>
```
* In order to be able to start using Forms in XMCloud you need to register a Form component and add required configuration:
* Update your _scripts/generate-component-builder_ template::
* Register Form component
```ts
const packages = [
{
name: '@sitecore-jss/sitecore-jss-angular',
components: [{ componentName: 'Form', moduleName: 'FormComponent' }],
},
]
```
Make sure to don't push such components to the "declarations" list, since the related module is a part of "imports" list.
* Add to "providers" list a new InjectionToken, EDGE_CONFIG token is needed for Form component to be able to fetch the form from Sitecore Edge:
```ts
import { EDGE_CONFIG } from '@sitecore-jss/sitecore-jss-angular';
import { environment } from '../../environments/environment';
...
providers: [
{
// This configuration is used to be able to integrate sitecore-jss-angular SDK with Sitecore Edge
provide: EDGE_CONFIG,
useValue: {
sitecoreEdgeUrl: environment.sitecoreEdgeUrl,
sitecoreEdgeContextId: environment.sitecoreEdgeContextId,
},
},
],
```
# @sitecore-jss/sitecore-jss-proxy
* Update the import statement
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ComponentFactoryPlugin, ComponentFactoryPluginConfig } from '..';

/**
* Provides custom packages configuration
*/
class PackagesPlugin implements ComponentFactoryPlugin {
order = 0;

exec(config: ComponentFactoryPluginConfig) {
/**
* You can specify components which you want to import from external/internal packages
* in format:
* {
* name: 'package name',
* components: [
* {
* componentName: 'component name', // component rendering name,
* moduleName: 'module name' // component name to import from the package
* }
* ]
* }
*/
config.packages = [
{
name: '@sitecore-jss/sitecore-jss-angular',
components: [{ componentName: 'Form', moduleName: 'FormComponent' }],
},
];

return config;
}
}

export const packagesPlugin = new PackagesPlugin();
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
export const componentFactoryTemplate = ({
imports,
components,
registrations,
lazyRegistrations,
declarations,
}: {
imports: string[];
components: string[];
registrations: string[];
lazyRegistrations: string[];
declarations: string[];
}) => `// Do not edit this file, it is auto-generated at build time!
// See scripts/generate-component-factory/index.ts to modify the generation of this file.
// Use app-components.shared.module.ts to modify the imports, etc of this module.
// Note: code-generation is optional! See ./.gitignore for directions to remove it,
// if you do not want it.
import { NgModule } from '@angular/core';
import { EDGE_CONFIG, JssModule } from '@sitecore-jss/sitecore-jss-angular';
import { AppComponentsSharedModule } from './app-components.shared.module';
import { environment } from '../../environments/environment';
${imports.join('\n')}
export const components = [
${components.map((c) => `'${c}'`).join(',\n ')}
];
@NgModule({
imports: [
AppComponentsSharedModule,
JssModule.withComponents([
${registrations.join('\n ')}
], [
${lazyRegistrations.join('\n ')}
]),
],
providers: [
{
// This configuration is used to be able to integrate sitecore-jss-angular SDK with Sitecore Edge
provide: EDGE_CONFIG,
useValue: {
sitecoreEdgeUrl: environment.sitecoreEdgeUrl,
sitecoreEdgeContextId: environment.sitecoreEdgeContextId,
},
},
],
exports: [
JssModule,
AppComponentsSharedModule,
],
declarations: [
${declarations.join('\n ')}
],
})
export class AppComponentsModule { }
`;
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"build": "npm-run-all --serial bootstrap build:client build:server",
"scaffold": "ng generate @sitecore-jss/sitecore-jss-angular-schematics:jss-component --no-manifest",
"start:angular": "ng serve -o",
"start:watch-components": "ts-node --project src/tsconfig.webpack-server.json scripts/generate-component-factory.ts --watch",
"start:watch-components": "ts-node --project src/tsconfig.webpack-server.json scripts/generate-component-factory/index.ts --watch",
"build:client": "cross-env-shell ng build --configuration=production --base-href $npm_package_config_sitecoreDistPath/browser/ --output-path=$npm_package_config_buildArtifactsPath/browser/",
"build:server": "cross-env-shell ng run <%- appName %>:server:production --output-path=$npm_package_config_buildArtifactsPath",
"postbuild:server": "move-cli ./dist/main.js ./dist/server.bundle.js",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const plugins = require('scripts/temp/generate-component-factory-plugins');
import { PackageDefinition } from '@sitecore-jss/sitecore-jss-dev-tools';

export interface ComponentFactoryPluginConfig {
watch?: boolean;
packages: PackageDefinition[];
components: string[];
}

export interface ComponentFactoryPlugin {
/**
* Detect order when the plugin should be called, e.g. 0 - will be called first (can be a plugin which data is required for other plugins)
*/
order: number;
/**
* A function which will be called during component factory generation
* @param {JssConfig} config Current (accumulated) config
*/
exec(config: ComponentFactoryPluginConfig): ComponentFactoryPluginConfig;
}

/*
COMPONENT FACTORY GENERATION
Generates the /src/app/components/app-components.module.ts file which maps Angular components
to JSS components.
The component factory module defines a mapping between a string component name and a Angular component instance.
When the Sitecore Layout service returns a layout definition, it returns named components.
This mapping is used to construct the component hierarchy for the layout.
NOTE: this script can run in two modes. The default mode, the component factory file is written once.
But if `--watch` is a process argument, the component factory source folder will be watched,
and the componentFactory.js rewritten on added or deleted files.
This is used during `jss start` to pick up new or removed components at runtime.
*/

const defaultConfig: ComponentFactoryPluginConfig = {
watch: process.argv.some(arg => arg === '--watch'),
packages: [],
components: [],
};

(Object.values(plugins) as ComponentFactoryPlugin[])
.sort((p1, p2) => p1.order - p2.order)
.reduce((config, plugin) => plugin.exec(config), defaultConfig);
Loading

0 comments on commit a0d83f1

Please sign in to comment.