Skip to content

Commit

Permalink
chore(sdk): Create dotCMS Angular library #28498 (#28661)
Browse files Browse the repository at this point in the history
### Proposed Changes
* Moved all SDK logic to standalone lib in NX workspace
* This PR introduces a new method to create a links from the example
apps to sdk libs, using compilerOptions on tsconfig file. To test it,
build the angular sdk lib and run the angular example

in core/core-web:
`npx nx run sdk-angular:build`

then `ng serve` in examples/angular

This way can be used in other sdk/examples apps

---------

Co-authored-by: KevinDavilaDotCMS <[email protected]>
  • Loading branch information
KevinDavilaDotCMS and kevindaviladev authored May 31, 2024
1 parent f70bf4a commit 3ae5654
Show file tree
Hide file tree
Showing 80 changed files with 2,358 additions and 734 deletions.
25 changes: 25 additions & 0 deletions core-web/libs/sdk/angular/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"extends": ["../../../.eslintrc.base.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": "error"
}
}
]
}
134 changes: 134 additions & 0 deletions core-web/libs/sdk/angular/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# @dotcms/angular

`@dotcms/angular` is the official set of Angular components, services and resolver designed to work seamlessly with dotCMS, making it easy to render dotCMS pages an use the page builder

## Features

- A collection of Angular components, services and resolver tailored to render
dotCMS pages.
- Streamlined integration with dotCMS page editor.
- Improved development experience with comprehensive TypeScript typings.

## Installation

Install the package via npm:

```bash
npm install @dotcms/angular
```

Or using Yarn:

```bash
yarn add @dotcms/angular
```

## Provider
```
const DOTCMS_CLIENT_CONFIG: ClientConfig = {
dotcmsUrl: environment.dotcmsUrl,
authToken: environment.authToken,
siteId: environment.siteId
};
```
Add the dotcms config in the Angular app ApplicationConfig
```
export const appConfig: ApplicationConfig = {
providers: [
provideDotcmsClient(DOTCMS_CLIENT_CONFIG),
provideRouter(routes),
],
};
```
## Resolver
```javascript
export const routes: Routes = [
{
path: '**',
resolve: {
// This should be called `context`.
context: DotCMSPageResolver,
},
component: DotCMSPagesComponent,
runGuardsAndResolvers: 'always' // Run the resolver on every navigation. Even if the URL hasn't changed.
},
];
```

Then, in your component, you can read the data using

```javascript
protected readonly context = signal(null);

ngOnInit() {
// Get the context data from the route
this.route.data.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(data => {
this.context.set(data['context']);
});
}
```
## Components

### `DotcmsLayoutComponent`

A component that renders a layout for a dotCMS page.

#### Inputs

- **entity**: The context for a dotCMS page.
- **components**: An object with the relation of contentlets and the component to render each.


#### Usage

```javascript
<dotcms-layout [entity]="pageAsset" [components]="components()" />

DYNAMIC_COMPONENTS: { [key: string]: DynamicComponentEntity } = {
Activity: import('../pages/content-types/activity/activity.component').then(
(c) => c.ActivityComponent,
),
Banner: import('../pages/content-types/banner/banner.component').then(
(c) => c.BannerComponent,
),
Image: import('../pages/content-types/image/image.component').then(
(c) => c.ImageComponent,
),
webPageContent: import(
'../pages/content-types/web-page-content/web-page-content.component'
).then((c) => c.WebPageContentComponent),
Product: import('../pages/content-types/product/product.component').then(
(c) => c.ProductComponent,
),
};

components = signal(DYNAMIC_COMPONENTS);
```

## Contributing

GitHub pull requests are the preferred method to contribute code to dotCMS. Before any pull requests can be accepted, an automated tool will ask you to agree to the [dotCMS Contributor's Agreement](https://gist.github.com/wezell/85ef45298c48494b90d92755b583acb3).

## Licensing

dotCMS comes in multiple editions and as such is dual licensed. The dotCMS Community Edition is licensed under the GPL 3.0 and is freely available for download, customization and deployment for use within organizations of all stripes. dotCMS Enterprise Editions (EE) adds a number of enterprise features and is available via a supported, indemnified commercial license from dotCMS. For the differences between the editions, see [the feature page](http://dotcms.com/cms-platform/features).

## Support

If you need help or have any questions, please [open an issue](https://github.com/dotCMS/core/issues/new/choose) in the GitHub repository.

## Documentation

Always refer to the official [DotCMS documentation](https://www.dotcms.com/docs/latest/) for comprehensive guides and API references.

## Getting Help

| Source | Location |
| --------------- | ------------------------------------------------------------------- |
| Installation | [Installation](https://dotcms.com/docs/latest/installation) |
| Documentation | [Documentation](https://dotcms.com/docs/latest/table-of-contents) |
| Videos | [Helpful Videos](http://dotcms.com/videos/) |
| Code Examples | [Codeshare](https://dotcms.com/codeshare/) |
| Forums/Listserv | [via Google Groups](https://groups.google.com/forum/#!forum/dotCMS) |
| Twitter | @dotCMS |
| Main Site | [dotCMS.com](https://dotcms.com/) |
22 changes: 22 additions & 0 deletions core-web/libs/sdk/angular/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable */
export default {
displayName: 'sdk-angular',
preset: '../../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../../coverage/libs/sdk/angular',
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$'
}
]
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment'
]
};
7 changes: 7 additions & 0 deletions core-web/libs/sdk/angular/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/libs/sdk/angular",
"lib": {
"entryFile": "src/index.ts"
}
}
31 changes: 31 additions & 0 deletions core-web/libs/sdk/angular/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@dotcms/angular",
"version": "0.0.1-alpha.17",
"peerDependencies": {
"@angular/common": "^17.1.0",
"@angular/core": "^17.1.0",
"@angular/router": "^17.1.0",
"@dotcms/client": "0.0.1-alpha.17",
"rxjs": "~6.6.3"
},
"description": "Official Angular Components library to render a dotCMS page.",
"repository": {
"type": "git",
"url": "git+https://github.com/dotCMS/core.git#master"
},
"keywords": [
"dotCMS",
"CMS",
"Content Management",
"API Client",
"REST API",
"Angular",
"Components"
],
"author": "dotcms <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/dotCMS/core/issues"
},
"homepage": "https://github.com/dotCMS/core/tree/master/core-web/libs/sdk/angular/README.md"
}
33 changes: 33 additions & 0 deletions core-web/libs/sdk/angular/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "sdk-angular",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/sdk/angular/src",
"prefix": "lib",
"tags": [],
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/angular:package",
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
"options": {
"project": "libs/sdk/angular/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "libs/sdk/angular/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "libs/sdk/angular/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/sdk/angular/jest.config.ts"
}
}
}
}
3 changes: 3 additions & 0 deletions core-web/libs/sdk/angular/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './lib/layout/dotcms-layout/dotcms-layout.component';
export * from './lib/services/dotcms-context/page-context.service';
export * from './lib/models';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:host {
display: block;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Spectator, createComponentFactory } from '@ngneat/spectator';

import { NoComponent } from './no-component.component';

import { DotCMSContentlet } from '../../models';

describe('NoComponentComponent', () => {
let spectator: Spectator<NoComponent>;

const createComponent = createComponentFactory(NoComponent);

beforeEach(() => {
spectator = createComponent({
props: {
contentlet: { contentType: 'exampleContentType' } as DotCMSContentlet
}
});
});

it('should display the content type', () => {
const noComponent = spectator.debugElement.nativeElement;
expect(noComponent?.innerHTML).toBe('No Component for exampleContentType');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core';

import { DotCMSContentlet } from '../../models';

/**
* This is part of the Angular SDK.
* This is a component for the `NoComponentComponent` component.
*/
@Component({
selector: 'dotcms-no-component',
standalone: true,
template: `No Component for {{ contentlet.contentType }}`,
styleUrl: './no-component.component.css',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class NoComponent {
@Input() contentlet!: DotCMSContentlet;
@HostBinding('attr.data-testid') testId = 'no-component';
}
Loading

0 comments on commit 3ae5654

Please sign in to comment.