mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-09-10 14:11:42 +00:00
AAE-32587 new custom screen registration api (#11120)
This commit is contained in:
@@ -200,7 +200,8 @@ module.exports = {
|
||||
files: ['*.spec.ts'],
|
||||
plugins: ['@alfresco/eslint-angular'],
|
||||
rules: {
|
||||
'@alfresco/eslint-angular/no-angular-material-selectors': 'error'
|
||||
'@alfresco/eslint-angular/no-angular-material-selectors': 'error',
|
||||
'@angular-eslint/component-class-suffix': 'off'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@@ -84,6 +84,13 @@
|
||||
"@angular-eslint/prefer-standalone": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.spec.ts"],
|
||||
"plugins": ["@alfresco/eslint-angular"],
|
||||
"rules": {
|
||||
"@angular-eslint/component-class-suffix": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"extends": ["plugin:@nx/angular-template"],
|
||||
|
@@ -16,10 +16,9 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ScreenRenderingService } from '../../../services/public-api';
|
||||
import { ScreenRenderingService } from '../../services/screen-rendering.service';
|
||||
import { TaskScreenCloudComponent } from './screen-cloud.component';
|
||||
|
||||
@Component({
|
||||
@@ -31,8 +30,7 @@ import { TaskScreenCloudComponent } from './screen-cloud.component';
|
||||
<div class="adf-cloud-test-container-rootProcessInstanceId">{{ rootProcessInstanceId }}</div>
|
||||
<button class="adf-cloud-test-container-complete-btn" (click)="onComplete()">complete</button>
|
||||
</div>
|
||||
`,
|
||||
imports: [CommonModule]
|
||||
`
|
||||
})
|
||||
class TestComponent {
|
||||
@Input() taskId = '';
|
||||
@@ -59,7 +57,7 @@ class TestComponent {
|
||||
(taskCompleted)="onTaskCompleted()"
|
||||
/>
|
||||
`,
|
||||
imports: [CommonModule, TaskScreenCloudComponent]
|
||||
imports: [TaskScreenCloudComponent]
|
||||
})
|
||||
class TestWrapperComponent {
|
||||
@Input() screenId = '';
|
||||
|
@@ -17,9 +17,9 @@
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, ComponentRef, DestroyRef, EventEmitter, inject, Input, OnInit, Output, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { ScreenRenderingService } from '../../../services/public-api';
|
||||
import { ScreenRenderingService } from '../../services/screen-rendering.service';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { UserTaskCustomUi } from '../../models/screen-cloud.model';
|
||||
import { UserTaskCustomUi } from './screen-cloud.model';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
|
||||
|
@@ -15,4 +15,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './models/screen-cloud.model';
|
||||
export * from './components/screen-cloud/screen-cloud.model';
|
||||
export * from './services/screen-rendering.service';
|
||||
export * from './services/provide-screen';
|
||||
|
@@ -0,0 +1,50 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { InjectionToken, Provider, Type } from '@angular/core';
|
||||
|
||||
export interface CustomScreen {
|
||||
key: string;
|
||||
component: Type<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injection token for custom screens.
|
||||
* This token can be used to inject custom screen components into the application.
|
||||
* It allows for multiple screen components to be registered and injected.
|
||||
*/
|
||||
export const APP_CUSTOM_SCREEN_TOKEN = new InjectionToken<CustomScreen>('Injection token for custom screens.');
|
||||
|
||||
/**
|
||||
* Provides a custom screen component to be used in the application.
|
||||
* This function allows you to register a custom screen component that can be injected
|
||||
* into the application using the `APP_CUSTOM_SCREEN_TOKEN`.
|
||||
*
|
||||
* @param key - A unique key to identify the screen component.
|
||||
* @param component - The screen component to be registered.
|
||||
* @returns A provider that can be used in the Angular dependency injection system.
|
||||
*/
|
||||
export function provideScreen(key: string, component: Type<any>): Provider {
|
||||
return {
|
||||
provide: APP_CUSTOM_SCREEN_TOKEN,
|
||||
multi: true,
|
||||
useValue: {
|
||||
key,
|
||||
component
|
||||
}
|
||||
};
|
||||
}
|
@@ -0,0 +1,123 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { Component } from '@angular/core';
|
||||
import { ScreenRenderingService } from './screen-rendering.service';
|
||||
import { APP_CUSTOM_SCREEN_TOKEN, provideScreen } from './provide-screen';
|
||||
|
||||
@Component({
|
||||
template: '<div>Test Component 1</div>'
|
||||
})
|
||||
class TestComponent1 {}
|
||||
|
||||
@Component({
|
||||
template: '<div>Test Component 2</div>'
|
||||
})
|
||||
class TestComponent2 {}
|
||||
|
||||
describe('ScreenRenderingService', () => {
|
||||
let service: ScreenRenderingService;
|
||||
|
||||
describe('without custom screens', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ScreenRenderingService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should handle empty custom screens array', () => {
|
||||
expect(service).toBeTruthy();
|
||||
expect(() => service).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom screens', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideScreen('test-screen-1', TestComponent1), provideScreen('test-screen-2', TestComponent2)]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created with custom screens', () => {
|
||||
const service = TestBed.inject(ScreenRenderingService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should register custom screens on initialization', () => {
|
||||
const spy = spyOn(ScreenRenderingService.prototype, 'setComponentTypeResolver');
|
||||
TestBed.inject(ScreenRenderingService);
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(2);
|
||||
expect(spy).toHaveBeenCalledWith('test-screen-1', jasmine.any(Function), true);
|
||||
expect(spy).toHaveBeenCalledWith('test-screen-2', jasmine.any(Function), true);
|
||||
});
|
||||
|
||||
it('should register component resolvers that return correct components', () => {
|
||||
const resolverCalls: any[] = [];
|
||||
spyOn(ScreenRenderingService.prototype, 'setComponentTypeResolver').and.callFake((key, resolver, override) => {
|
||||
resolverCalls.push({ key, resolver: resolver({ type: key }), override });
|
||||
});
|
||||
TestBed.inject(ScreenRenderingService);
|
||||
|
||||
expect(resolverCalls).toEqual([
|
||||
{ key: 'test-screen-1', resolver: TestComponent1, override: true },
|
||||
{ key: 'test-screen-2', resolver: TestComponent2, override: true }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with single custom screen', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideScreen('single-screen', TestComponent1)]
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle single custom screen', () => {
|
||||
const spy = spyOn(ScreenRenderingService.prototype, 'setComponentTypeResolver');
|
||||
TestBed.inject(ScreenRenderingService);
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
expect(spy).toHaveBeenCalledWith('single-screen', jasmine.any(Function), true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with null custom screens', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: APP_CUSTOM_SCREEN_TOKEN,
|
||||
useValue: null,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle null custom screens gracefully', () => {
|
||||
expect(() => {
|
||||
service = TestBed.inject(ScreenRenderingService);
|
||||
}).not.toThrow();
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
@@ -0,0 +1,67 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DynamicComponentMapper } from '@alfresco/adf-core';
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { APP_CUSTOM_SCREEN_TOKEN, CustomScreen } from './provide-screen';
|
||||
|
||||
/**
|
||||
* Service for managing and rendering custom screen components.
|
||||
*
|
||||
* Custom screens can be registered using the {@link provideScreen} helper function
|
||||
* and the {@link APP_CUSTOM_SCREEN_TOKEN} injection token.
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* // Register a custom screen in your Angular module providers:
|
||||
* import { provideScreen, ScreenRenderingService } from '@alfresco/adf-process-services-cloud';
|
||||
*
|
||||
* @Component({
|
||||
* template: '<div>My Custom Screen</div>'
|
||||
* })
|
||||
* class MyCustomScreenComponent {}
|
||||
*
|
||||
* @NgModule({
|
||||
* providers: [
|
||||
* provideScreen('my-custom-screen', MyCustomScreenComponent)
|
||||
* ]
|
||||
* })
|
||||
* export class MyModule {}
|
||||
*
|
||||
* // The custom screen can now be resolved and rendered by ScreenRenderingService.
|
||||
* ```
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ScreenRenderingService extends DynamicComponentMapper {
|
||||
private customScreens = inject<CustomScreen[]>(APP_CUSTOM_SCREEN_TOKEN, { optional: true }) || [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.registerCustomScreens();
|
||||
}
|
||||
|
||||
private registerCustomScreens() {
|
||||
if (this.customScreens && this.customScreens.length > 0) {
|
||||
this.customScreens.forEach((screen) => {
|
||||
if (!screen) return; // Skip null or undefined screens
|
||||
this.setComponentTypeResolver(screen.key, () => screen.component, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -21,7 +21,6 @@ export * from './form-fields.interfaces';
|
||||
export * from './local-preference-cloud.service';
|
||||
export * from './notification-cloud.service';
|
||||
export * from './preference-cloud.interface';
|
||||
export * from './screen-rendering.service';
|
||||
export * from './task-list-cloud.service.interface';
|
||||
export * from './user-preference-cloud.service';
|
||||
export * from './variable-mapper.sevice';
|
||||
|
@@ -1,32 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { ScreenRenderingService } from './screen-rendering.service';
|
||||
|
||||
describe('ScreenRenderingService', () => {
|
||||
let service: ScreenRenderingService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ScreenRenderingService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -1,24 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DynamicComponentMapper } from '@alfresco/adf-core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ScreenRenderingService extends DynamicComponentMapper {}
|
Reference in New Issue
Block a user