Skip to content

Commit c88d069

Browse files
committed
[NAE-2116] Frontend remote configuration
- rework based on pr comments - fix tests
1 parent f30a8ce commit c88d069

File tree

12 files changed

+167
-39
lines changed

12 files changed

+167
-39
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import {Injectable} from '@angular/core';
2-
import {ApplicationConfiguration, ConfigurationService, ResourceProvider, NetgrifApplicationEngine} from '@netgrif/components-core';
2+
import {ApplicationConfiguration, ConfigurationService, NetgrifApplicationEngine, ConfigurationResourceService} from '@netgrif/components-core';
33
import {default as naeConfig} from '../../../../nae.json';
44
import {environment} from '../environments/environment';
55

66
@Injectable({
77
providedIn: 'root'
88
})
99
export class NaeExampleAppConfigurationService extends ConfigurationService {
10-
constructor(private resourceProvider: ResourceProvider) {
10+
constructor(protected _configurationResource: ConfigurationResourceService) {
1111
const applicationConfig: ApplicationConfiguration = {
1212
application: environment.application_identifier,
1313
type: environment.type_identifier,
1414
gateway_url: environment.gateway_url,
1515
resolve_configuration: environment.resolve_configuration
1616
};
17-
super(naeConfig as unknown as NetgrifApplicationEngine, resourceProvider, applicationConfig);
17+
super(naeConfig as unknown as NetgrifApplicationEngine, _configurationResource, applicationConfig);
1818
}
1919
}

projects/nae-example-app/src/assets/env.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
window['env']['gateway_url'] = 'http://localhost:8800/api';
66
window['env']['application_identifier'] = 'nae';
77
window['env']['type_identifier'] = 'default';
8-
})(this);
8+
})(window);

projects/nae-example-app/src/assets/env.template.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
window['env']['gateway_url'] = "${GATEWAY_URL}";
66
window['env']['application_identifier'] = "${APPLICATION_IDENTIFIER}";
77
window['env']['type_identifier'] = "${TYPE_IDENTIFIER}";
8-
})(this);
8+
})(window);

projects/nae-example-app/src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<base href="/">
77
<meta name="viewport" content="width=device-width, initial-scale=1">
88
<link rel="icon" type="image/x-icon" href="favicon.ico">
9-
<script src="./assets/env.js"></script>
9+
<script src="assets/env.js"></script>
1010
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
1111
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
1212
</head>

projects/netgrif-components-core/src/lib/authentication/profile/services/profile.service.spec.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import {RouterTestingModule} from '@angular/router/testing';
77
import {ProfileService} from './profile.service';
88
import {NetgrifApplicationEngine} from "../../../../commons/schema";
99
import {UserChangePasswordRequest} from "../models/user-change-password-request";
10+
import {ConfigurationResourceService} from '../../../resources/engine-endpoint/configuration-resource.service';
11+
import {ResourceProvider} from '../../../resources/resource-provider.service';
12+
import {HttpClient} from '@angular/common/http';
13+
import {Injectable} from '@angular/core';
1014

1115
describe('ProfileService', () => {
1216
let service: ProfileService;
@@ -56,6 +60,9 @@ describe('ProfileService', () => {
5660
TestBed.configureTestingModule({
5761
imports: [HttpClientTestingModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])],
5862
providers: [
63+
HttpClient,
64+
ResourceProvider,
65+
ConfigurationResourceService,
5966
ProfileService,
6067
{provide: ConfigurationService, useClass: MissingEndpointsConfigurationService}
6168
]
@@ -74,8 +81,9 @@ describe('ProfileService', () => {
7481
});
7582
});
7683

84+
@Injectable()
7785
class MissingEndpointsConfigurationService extends ConfigurationService {
78-
constructor() {
86+
constructor(protected configurationResource: ConfigurationResourceService) {
7987
super({
8088
extends: 'nae-default',
8189
providers: {
@@ -89,6 +97,13 @@ class MissingEndpointsConfigurationService extends ConfigurationService {
8997
},
9098
resources: []
9199
}
92-
} as unknown as NetgrifApplicationEngine);
100+
} as unknown as NetgrifApplicationEngine,
101+
configurationResource,
102+
{
103+
application: 'nae',
104+
type: 'default',
105+
gateway_url: 'http://localhost:8888/api',
106+
resolve_configuration: false
107+
});
93108
}
94109
}

projects/netgrif-components-core/src/lib/authentication/sign-up/services/sign-up.service.spec.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import {HttpClientTestingModule, HttpTestingController} from '@angular/common/ht
66
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
77
import {RouterTestingModule} from '@angular/router/testing';
88
import {NetgrifApplicationEngine} from '../../../../commons/schema';
9+
import {ConfigurationResourceService} from '../../../resources/engine-endpoint/configuration-resource.service';
10+
import {ResourceProvider} from '../../../resources/resource-provider.service';
11+
import {HttpClient} from '@angular/common/http';
12+
import {Injectable} from '@angular/core';
913

1014
describe('SignUpService', () => {
1115
let service: SignUpService;
@@ -85,6 +89,9 @@ describe('SignUpService', () => {
8589
TestBed.configureTestingModule({
8690
imports: [HttpClientTestingModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])],
8791
providers: [
92+
HttpClient,
93+
ResourceProvider,
94+
ConfigurationResourceService,
8895
SignUpService,
8996
{provide: ConfigurationService, useClass: MissingEndpointsConfigurationService}
9097
]
@@ -118,8 +125,9 @@ describe('SignUpService', () => {
118125
});
119126
});
120127

128+
@Injectable()
121129
class MissingEndpointsConfigurationService extends ConfigurationService {
122-
constructor() {
130+
constructor(protected configurationResource: ConfigurationResourceService) {
123131
super({
124132
extends: 'nae-default',
125133
providers: {
@@ -135,6 +143,13 @@ class MissingEndpointsConfigurationService extends ConfigurationService {
135143
},
136144
resources: []
137145
}
138-
} as unknown as NetgrifApplicationEngine);
146+
} as unknown as NetgrifApplicationEngine,
147+
configurationResource,
148+
{
149+
application: 'nae',
150+
type: 'default',
151+
gateway_url: 'http://localhost:8888/api',
152+
resolve_configuration: false
153+
});
139154
}
140155
}

projects/netgrif-components-core/src/lib/configuration/configuration.service.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {NetgrifApplicationEngine, Services, View, Views} from '../../commons/schema';
22
import {Observable, of} from 'rxjs';
3-
import {ResourceProvider} from '../resources/resource-provider.service';
43
import {ApplicationConfiguration} from './application-configuration';
4+
import {ConfigurationResourceService} from '../resources/engine-endpoint/configuration-resource.service';
5+
import {tap} from 'rxjs/operators';
56

67

78
export abstract class ConfigurationService {
@@ -11,7 +12,7 @@ export abstract class ConfigurationService {
1112
private readonly APPLICATION_CONFIG: ApplicationConfiguration;
1213

1314
protected constructor(protected configuration: NetgrifApplicationEngine,
14-
protected _resourceProvider: ResourceProvider,
15+
protected _configurationResource: ConfigurationResourceService,
1516
protected _applicationConfiguration: ApplicationConfiguration) {
1617
this.initialize();
1718

@@ -260,27 +261,29 @@ export abstract class ConfigurationService {
260261
}
261262

262263
/**
263-
* Loads the configuration for the application by fetching data from the resource provider
264-
* and initializes the application settings based on the fetched configuration.
264+
* Loads and initializes application configuration from the backend.
265+
* If configuration resolution is disabled in APPLICATION_CONFIG, returns null Observable.
266+
* Otherwise fetches public configuration via ConfigurationResourceService.
265267
*
266-
* @return {Promise<any>} A promise that resolves with the fetched configuration or returns null
267-
* if the configuration resolution is not enabled.
268+
* @returns Observable<any> that emits null if resolution is disabled, otherwise emits the loaded configuration
269+
* @fires initialize() Upon successful configuration load to setup endpoints and data field configurations
270+
* @see ApplicationConfiguration
271+
* @see NetgrifApplicationEngine
268272
*/
269-
public loadConfiguration(): Promise<any> {
273+
public loadConfiguration(): Observable<any> {
270274
if (!this.APPLICATION_CONFIG.resolve_configuration) {
271-
return null;
275+
return of(null);
272276
}
273-
return this._resourceProvider.get$(
274-
`/frontend-config/public/${this.APPLICATION_CONFIG.application}/${this.APPLICATION_CONFIG.type}`,
275-
this.APPLICATION_CONFIG.gateway_url
276-
).toPromise()
277-
.then((data: ApplicationConfiguration) => {
278-
if (!data || !data.properties) {
279-
return;
280-
}
281-
this.configuration = data.properties as NetgrifApplicationEngine;
282-
this.initialize();
283-
});
277+
return this._configurationResource.getPublicApplicationConfiguration(this.APPLICATION_CONFIG)
278+
.pipe(
279+
tap((data: ApplicationConfiguration) => {
280+
if (!data || !data.properties) {
281+
return;
282+
}
283+
this.configuration = data.properties as NetgrifApplicationEngine;
284+
this.initialize();
285+
})
286+
);
284287
}
285288

286289
private createConfigurationCopy(): any {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { ConfigurationResourceService } from './configuration-resource.service';
4+
import {HttpClientTestingModule} from '@angular/common/http/testing';
5+
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
6+
import {HttpClient} from '@angular/common/http';
7+
8+
describe('ConfigurationResourceService', () => {
9+
let service: ConfigurationResourceService;
10+
11+
beforeEach(() => {
12+
TestBed.configureTestingModule({
13+
imports: [HttpClientTestingModule, NoopAnimationsModule],
14+
providers: [HttpClient]
15+
});
16+
service = TestBed.inject(ConfigurationResourceService);
17+
});
18+
19+
it('should be created', () => {
20+
expect(service).toBeTruthy();
21+
});
22+
});
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {Injectable} from '@angular/core';
2+
import {ResourceProvider} from '../resource-provider.service';
3+
import {ApplicationConfiguration} from '../../configuration/application-configuration';
4+
import {Observable} from 'rxjs';
5+
6+
/**
7+
* @class ConfigurationResourceService
8+
* @description Service responsible for retrieving frontend application configurations via HTTP requests.
9+
* Provides a RESTful interface for accessing public application configuration endpoints.
10+
*
11+
* @injectable Provided at root level for application-wide singleton instance
12+
*/
13+
@Injectable({
14+
providedIn: 'root'
15+
})
16+
export class ConfigurationResourceService {
17+
18+
/**
19+
* Base URL segment for configuration resource endpoints
20+
*/
21+
private readonly RESOURCE_URL: string = "frontend-config";
22+
23+
/**
24+
* URL segment identifier for public configuration endpoints
25+
*/
26+
private readonly PUBLIC_SUFFIX: string = "public";
27+
28+
constructor(protected _provider: ResourceProvider) {}
29+
30+
/**
31+
* Retrieves public application configuration from the backend
32+
*
33+
* @param {ApplicationConfiguration} configuration - Configuration object containing application metadata
34+
* @returns {Observable<ApplicationConfiguration>} Observable that emits the public application configuration
35+
*
36+
* @description Makes a GET request to /frontend-config/public/{app}/{type} endpoint
37+
* Uses the provided gateway URL from the configuration object
38+
*/
39+
public getPublicApplicationConfiguration(configuration: ApplicationConfiguration): Observable<ApplicationConfiguration> {
40+
return this._provider.get$(
41+
`/${this.RESOURCE_URL}/${this.PUBLIC_SUFFIX}/${configuration.application}/${configuration.type}`,
42+
configuration.gateway_url
43+
);
44+
}
45+
}

projects/netgrif-components-core/src/lib/resources/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './engine-endpoint/petri-net-resource.service';
66
export * from './engine-endpoint/user-resource.service';
77
export * from './engine-endpoint/dashboard-resource.service';
88
export * from './engine-endpoint/ldap-group-resource.service';
9+
export * from './engine-endpoint/configuration-resource.service';
910

1011
/* PUBLIC SERVICES */
1112
export * from './engine-endpoint/public/public-case-resource.service';

0 commit comments

Comments
 (0)