Skip to content

Commit 4ce2287

Browse files
authored
Merge branch 'main' into feat/better-support-jsonpath
2 parents c37de21 + 71b415a commit 4ce2287

File tree

13 files changed

+1332
-917
lines changed

13 files changed

+1332
-917
lines changed

package-lock.json

Lines changed: 983 additions & 898 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@platform-mesh/portal-ui-lib",
3-
"version": "0.21.12",
3+
"version": "0.21.15",
44
"repository": {
55
"url": "git+https://github.com/platform-mesh/portal-ui-lib.git"
66
},
@@ -26,16 +26,16 @@
2626
"tslib": "2.8.1"
2727
},
2828
"devDependencies": {
29-
"@angular-builders/jest": "20.0.0",
30-
"@angular-devkit/build-angular": "20.3.8",
31-
"@angular-eslint/builder": "20.5.1",
32-
"@angular/build": "20.3.8",
33-
"@angular/cli": "20.3.8",
34-
"@angular/compiler-cli": "20.3.9",
35-
"@angular/localize": "20.3.9",
29+
"@angular-builders/jest": "^20.0.0",
30+
"@angular-devkit/build-angular": "^20.3.13",
31+
"@angular-eslint/builder": "^20.5.2",
32+
"@angular/build": "^20.3.13",
33+
"@angular/cli": "^20.3.13",
34+
"@angular/compiler-cli": "^20.3.15",
35+
"@angular/localize": "^20.3.15",
3636
"@briebug/jest-schematic": "6.0.0",
3737
"@openmfp/config-prettier": "0.9.2",
38-
"@openmfp/portal-ui-lib": "0.184.11",
38+
"@openmfp/portal-ui-lib": "0.184.15",
3939
"@types/jest": "30.0.0",
4040
"@types/jmespath": "0.15.2",
4141
"@types/jsonpath": "0.2.4",

projects/lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
},
1313
"prettier": "@openmfp/config-prettier",
1414
"peerDependencies": {
15-
"@openmfp/portal-ui-lib": "0.184.11"
15+
"@openmfp/portal-ui-lib": "0.184.15"
1616
}
1717
}

projects/lib/portal-options/services/custom-global-nodes.service.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { kcpRootOrgsPath } from '../models/constants';
22
import { PortalNodeContext } from '../models/luigi-context';
33
import { PortalLuigiNode } from '../models/luigi-node';
44
import { inject } from '@angular/core';
5-
import { CustomGlobalNodesService, I18nService } from '@openmfp/portal-ui-lib';
5+
import {
6+
CustomGlobalNodesService,
7+
EntityType,
8+
I18nService,
9+
NodeContext,
10+
} from '@openmfp/portal-ui-lib';
611

712
export class CustomGlobalNodesServiceImpl implements CustomGlobalNodesService {
813
private i18nService = inject(I18nService);
@@ -25,6 +30,28 @@ export class CustomGlobalNodesServiceImpl implements CustomGlobalNodesService {
2530
kcpPath: kcpRootOrgsPath,
2631
} as PortalNodeContext,
2732
},
33+
{
34+
pathSegment: 'error',
35+
order: '1000',
36+
hideFromNav: true,
37+
context: {} as PortalNodeContext,
38+
children: [
39+
{
40+
pathSegment: ':id',
41+
entityType: EntityType.ENTITY_ERROR,
42+
hideFromNav: true,
43+
hideSideNav: true,
44+
viewUrl: '/assets/platform-mesh-portal-ui-wc.js#error-component',
45+
context: {
46+
id: ':id',
47+
translationTable: this.i18nService.translationTable,
48+
} as any as NodeContext,
49+
webcomponent: {
50+
selfRegistered: true,
51+
},
52+
},
53+
],
54+
},
2855
{
2956
pathSegment: 'users',
3057
showBreadcrumbs: false,

projects/lib/portal-options/services/router-config.service.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe('CustomRoutingConfigServiceImpl', () => {
9292
const result = await config.pageNotFoundHandler();
9393

9494
expect(result).toEqual({
95-
redirectTo: 'welcome',
95+
redirectTo: 'error/404',
9696
keepURL: true,
9797
});
9898
});
@@ -111,7 +111,7 @@ describe('CustomRoutingConfigServiceImpl', () => {
111111
const result = await config.pageNotFoundHandler();
112112

113113
expect(result).toEqual({
114-
redirectTo: 'error/404',
114+
redirectTo: 'welcome',
115115
keepURL: true,
116116
});
117117
});
@@ -171,7 +171,7 @@ describe('CustomRoutingConfigServiceImpl', () => {
171171
const result = await config.pageNotFoundHandler();
172172

173173
expect(result).toEqual({
174-
redirectTo: 'error/404',
174+
redirectTo: 'welcome',
175175
keepURL: true,
176176
});
177177
});
@@ -190,7 +190,7 @@ describe('CustomRoutingConfigServiceImpl', () => {
190190
const result = await config.pageNotFoundHandler();
191191

192192
expect(result).toEqual({
193-
redirectTo: 'welcome',
193+
redirectTo: 'error/404',
194194
keepURL: true,
195195
});
196196
});
@@ -215,7 +215,7 @@ describe('CustomRoutingConfigServiceImpl', () => {
215215
const result = await config.pageNotFoundHandler();
216216

217217
expect(result).toEqual({
218-
redirectTo: 'error/404',
218+
redirectTo: 'welcome',
219219
keepURL: true,
220220
});
221221
});

projects/lib/portal-options/services/router-config.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ export class CustomRoutingConfigServiceImpl implements RoutingConfigService {
2020

2121
getRoutingConfig(): any {
2222
return {
23-
pageNotFoundHandler: async () => {
23+
pageNotFoundHandler: () => {
2424
if (!this.envConfig?.baseDomain) {
2525
return this.redirectTo('error/404');
2626
}
2727

28-
if (window.location.hostname !== this.envConfig.baseDomain) {
28+
if (window.location.hostname === this.envConfig.baseDomain) {
2929
return this.redirectTo('welcome');
3030
}
3131

projects/wc/_mocks_/ui5-mock.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,26 @@ jest.mock('@ui5/webcomponents-icons/dist/hide.js', () => ({}), {
4040
});
4141
jest.mock('@ui5/webcomponents-icons/dist/show.js', () => ({}), {
4242
virtual: true,
43-
});
43+
});
44+
45+
jest.mock(
46+
'@ui5/webcomponents-fiori/dist/illustrations/NoEntries.js',
47+
() => ({}),
48+
{
49+
virtual: true,
50+
},
51+
);
52+
jest.mock(
53+
'@ui5/webcomponents-fiori/dist/illustrations/UnableToLoad.js',
54+
() => ({}),
55+
{
56+
virtual: true,
57+
},
58+
);
59+
jest.mock(
60+
'@ui5/webcomponents-fiori/dist/illustrations/tnt/UnsuccessfulAuth.js',
61+
() => ({}),
62+
{
63+
virtual: true,
64+
},
65+
);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@let configVM = config();
2+
@if (configVM.scene) {
3+
<div class="page">
4+
<div class="container">
5+
<ui5-illustrated-message [name]="configVM.scene">
6+
<ui5-title slot="title" level="H1">{{configVM.illustratedMessageTitle}}</ui5-title>
7+
<div slot="subtitle">
8+
<p>{{configVM.illustratedMessageText}}</p>
9+
</div>
10+
<div>
11+
@for (button of configVM.buttons; track button.url) {
12+
<ui5-button
13+
design="Transparent"
14+
(click)="goTo(button)"
15+
>
16+
{{ button.label }}
17+
</ui5-button>
18+
}
19+
</div>
20+
</ui5-illustrated-message>
21+
</div>
22+
</div>
23+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { ErrorComponent } from './error.component';
2+
import { ButtonConfig } from './models/error.model';
3+
import { ComponentFixture, TestBed } from '@angular/core/testing';
4+
import { I18nService, LuigiCoreService } from '@openmfp/portal-ui-lib';
5+
import {
6+
ButtonComponent,
7+
IllustratedMessageComponent,
8+
TitleComponent,
9+
} from '@ui5/webcomponents-ngx';
10+
11+
describe('ErrorComponent', () => {
12+
let component: ErrorComponent;
13+
let fixture: ComponentFixture<ErrorComponent>;
14+
let i18nServiceMock: jest.Mocked<I18nService>;
15+
let luigiCoreServiceMock: jest.Mocked<LuigiCoreService>;
16+
17+
beforeEach(async () => {
18+
i18nServiceMock = {
19+
getTranslationAsync: jest.fn().mockResolvedValue('translated text'),
20+
translationTable: {},
21+
} as any;
22+
23+
luigiCoreServiceMock = {
24+
navigation: jest.fn().mockReturnValue({
25+
navigate: jest.fn(),
26+
}),
27+
showAlert: jest.fn(),
28+
} as any;
29+
30+
await TestBed.configureTestingModule({
31+
imports: [
32+
ErrorComponent,
33+
IllustratedMessageComponent,
34+
ButtonComponent,
35+
TitleComponent,
36+
],
37+
providers: [
38+
{ provide: I18nService, useValue: i18nServiceMock },
39+
{ provide: LuigiCoreService, useValue: luigiCoreServiceMock },
40+
],
41+
}).compileComponents();
42+
43+
fixture = TestBed.createComponent(ErrorComponent);
44+
component = fixture.componentInstance;
45+
});
46+
47+
it('should create', () => {
48+
expect(component).toBeTruthy();
49+
});
50+
51+
describe('goTo', () => {
52+
it('should open URL in new tab', () => {
53+
const windowSpy = jest.spyOn(window, 'open').mockImplementation();
54+
const button: ButtonConfig = { url: 'https://test.com' };
55+
56+
component.goTo(button);
57+
expect(windowSpy).toHaveBeenCalledWith('https://test.com', '_blank');
58+
});
59+
60+
it('should navigate using LuigiCore when route is provided', () => {
61+
const button: ButtonConfig = { route: { context: 'test-route' } };
62+
const navigateSpy = jest.fn();
63+
jest
64+
.spyOn(luigiCoreServiceMock, 'navigation')
65+
.mockReturnValue({ navigate: navigateSpy });
66+
67+
component.goTo(button);
68+
expect(navigateSpy).toHaveBeenCalledWith('/test-route');
69+
});
70+
});
71+
72+
describe('setSceneConfig', () => {
73+
it('should set 404 config', async () => {
74+
const testContext = {
75+
id: '404',
76+
translationTable: {},
77+
};
78+
79+
fixture.componentRef.setInput('context', testContext);
80+
81+
await component.ngOnInit();
82+
expect(component.config().scene).toBe('NoEntries');
83+
expect(component.config().illustratedMessageTitle).toBe('translated text');
84+
expect(component.config().illustratedMessageText).toBe('translated text');
85+
expect(component.config().buttons).toBeDefined();
86+
});
87+
88+
it('should set 403 config', async () => {
89+
const testContext = {
90+
id: '403',
91+
translationTable: {},
92+
};
93+
94+
fixture.componentRef.setInput('context', testContext);
95+
96+
await component.ngOnInit();
97+
expect(component.config().scene).toBe('tnt/UnsuccessfulAuth');
98+
expect(component.config().illustratedMessageTitle).toBe('');
99+
expect(component.config().illustratedMessageText).toBe('translated text');
100+
expect(component.config().buttons).toBeDefined();
101+
expect(component.config().buttons?.length).toBe(2);
102+
});
103+
104+
it('should set default error config for unknown error code', async () => {
105+
const testContext = {
106+
id: '500',
107+
translationTable: {},
108+
};
109+
110+
fixture.componentRef.setInput('context', testContext);
111+
112+
await component.ngOnInit();
113+
expect(component.config().scene).toBe('UnableToLoad');
114+
expect(component.config().illustratedMessageTitle).toBe('translated text');
115+
expect(component.config().illustratedMessageText).toBe('');
116+
expect(component.config().buttons).toBeDefined();
117+
});
118+
});
119+
});

0 commit comments

Comments
 (0)