@scion/workbench 20.0.0-beta.6 → 20.0.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/scion-workbench.mjs +116 -44
- package/fesm2022/scion-workbench.mjs.map +1 -1
- package/index.d.ts +13 -11
- package/package.json +2 -2
|
@@ -19,7 +19,7 @@ import * as i1 from '@angular/forms';
|
|
|
19
19
|
import { NonNullableFormBuilder, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
20
20
|
import { FocusMonitor, CdkTrapFocus } from '@angular/cdk/a11y';
|
|
21
21
|
import { trigger, transition, style, animate } from '@angular/animations';
|
|
22
|
-
import { ManifestService, MicrofrontendPlatform, PlatformState, MessageHeaders, MessageClient, ResponseStatusCodes, OutletRouter, MicrofrontendPlatformConfig, APP_IDENTITY,
|
|
22
|
+
import { ManifestService, MicrofrontendPlatform, PlatformState, MessageHeaders, MessageClient, ResponseStatusCodes, mapToBody, OutletRouter, MicrofrontendPlatformConfig, APP_IDENTITY, HostManifestInterceptor, ObservableDecorator, IntentInterceptor, CapabilityInterceptor, MicrofrontendPlatformHost, IntentClient, PlatformPropertyService } from '@scion/microfrontend-platform';
|
|
23
23
|
import { Beans } from '@scion/toolkit/bean-manager';
|
|
24
24
|
import { ɵMicrofrontendRouteParams as _MicrofrontendRouteParams, WorkbenchCapabilities, WorkbenchTextService, WorkbenchMessageBox, eMESSAGE_BOX_MESSAGE_PARAM, ɵTHEME_CONTEXT_KEY as _THEME_CONTEXT_KEY, ɵWorkbenchCommands as _WorkbenchCommands, ɵPOPUP_CONTEXT as _POPUP_CONTEXT, ɵWorkbenchPopupMessageHeaders as _WorkbenchPopupMessageHeaders, WorkbenchPopup, ɵMESSAGE_BOX_CONTEXT as _MESSAGE_BOX_CONTEXT, ɵDIALOG_CONTEXT as _DIALOG_CONTEXT, ɵWorkbenchDialogMessageHeaders as _WorkbenchDialogMessageHeaders, WorkbenchDialog as WorkbenchDialog$1, WorkbenchRouter as WorkbenchRouter$1, WorkbenchPopupService, WorkbenchMessageBoxService as WorkbenchMessageBoxService$1, ɵWorkbenchMessageBoxService as _WorkbenchMessageBoxService, WorkbenchDialogService as WorkbenchDialogService$1, ɵWorkbenchDialogService as _WorkbenchDialogService, WorkbenchNotificationService, ɵWorkbenchTextService as _WorkbenchTextService, ɵVIEW_ID_CONTEXT_KEY as _VIEW_ID_CONTEXT_KEY, WorkbenchClient } from '@scion/workbench-client';
|
|
25
25
|
import { SciThrobberComponent } from '@scion/components/throbber';
|
|
@@ -5570,22 +5570,22 @@ function parseMatrixParams(matrixParams) {
|
|
|
5570
5570
|
return {};
|
|
5571
5571
|
}
|
|
5572
5572
|
const params = {};
|
|
5573
|
-
for (const match of
|
|
5573
|
+
for (const match of encodeEscapedSemicolons(matrixParams).matchAll(/(?<paramName>[^=;]+)=(?<paramValue>[^;]*)/g)) {
|
|
5574
5574
|
const { paramName, paramValue } = match.groups;
|
|
5575
|
-
params[
|
|
5575
|
+
params[paramName] = decodeSemicolons(paramValue);
|
|
5576
5576
|
}
|
|
5577
5577
|
return params;
|
|
5578
5578
|
/**
|
|
5579
|
-
*
|
|
5579
|
+
* Encodes escaped semicolons (`\\;`) as `;` (Unicode) to prevent interpretation as interpolation parameter separators.
|
|
5580
5580
|
*/
|
|
5581
|
-
function
|
|
5582
|
-
return value.replaceAll('\\;', '
|
|
5581
|
+
function encodeEscapedSemicolons(value) {
|
|
5582
|
+
return value.replaceAll('\\;', ';');
|
|
5583
5583
|
}
|
|
5584
5584
|
/**
|
|
5585
|
-
*
|
|
5585
|
+
* Decodes encoded semicolons (`;`) back to semicolons (`;`).
|
|
5586
5586
|
*/
|
|
5587
|
-
function
|
|
5588
|
-
return value.replaceAll('
|
|
5587
|
+
function decodeSemicolons(value) {
|
|
5588
|
+
return value.replaceAll(';', ';');
|
|
5589
5589
|
}
|
|
5590
5590
|
}
|
|
5591
5591
|
|
|
@@ -14359,47 +14359,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
|
|
|
14359
14359
|
/**
|
|
14360
14360
|
* Registers a text provider for the SCION Workbench to get texts from micro apps.
|
|
14361
14361
|
*
|
|
14362
|
-
*
|
|
14363
|
-
* If not, the key is ignored and `undefined` is returned.
|
|
14364
|
-
*
|
|
14365
|
-
* Remote key format: "workbench.external.~<APP_SYMBOLIC_NAME>~.<TEXT_KEY>".
|
|
14362
|
+
* This text provider provides texts for keys matching the format: "workbench.external.scion-workbench-client.<APP_SYMBOLIC_NAME>.<TRANSLATABLE>".
|
|
14366
14363
|
*
|
|
14367
14364
|
* @see createRemoteTranslatable
|
|
14368
14365
|
*/
|
|
14369
14366
|
function provideRemoteTextProvider() {
|
|
14370
|
-
const
|
|
14367
|
+
const REMOTE_TRANSLATION_KEY = /^workbench\.external\.scion-workbench-client\.(?<provider>[^\\.]+)\.%(?<key>.+)$/;
|
|
14368
|
+
const REMOTE_TEXT = /^workbench\.external\.scion-workbench-client\.(?<provider>[^\\.]+)\.(?<text>[^%].+)$/;
|
|
14371
14369
|
return makeEnvironmentProviders([
|
|
14372
14370
|
{
|
|
14373
14371
|
provide: WORKBENCH_TEXT_PROVIDER,
|
|
14374
|
-
useValue:
|
|
14372
|
+
useValue: provideRemoteText,
|
|
14373
|
+
multi: true,
|
|
14374
|
+
},
|
|
14375
|
+
{
|
|
14376
|
+
provide: WORKBENCH_TEXT_PROVIDER,
|
|
14377
|
+
useValue: interpolateRemoteText,
|
|
14375
14378
|
multi: true,
|
|
14376
14379
|
},
|
|
14377
14380
|
]);
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
+
/**
|
|
14382
|
+
* Provides text from a remote app.
|
|
14383
|
+
*/
|
|
14384
|
+
function provideRemoteText(translationKey, params) {
|
|
14385
|
+
// Test if the key matches a remote translation key.
|
|
14386
|
+
const match = REMOTE_TRANSLATION_KEY.exec(translationKey);
|
|
14381
14387
|
if (!match) {
|
|
14382
|
-
return undefined;
|
|
14388
|
+
return undefined;
|
|
14383
14389
|
}
|
|
14384
|
-
// Parse key and provider from the remote key.
|
|
14390
|
+
// Parse key and provider from the remote translation key.
|
|
14385
14391
|
const { key, provider } = match.groups;
|
|
14386
14392
|
// Request the text by intent. Parameters starting with the topic protocol 'topic://' are resolved via messaging.
|
|
14387
|
-
const text$ = observeParams$(params)
|
|
14388
|
-
.pipe(map$1(params => params.reduce((translatable, [
|
|
14393
|
+
const text$ = observeParams$(params, { provider })
|
|
14394
|
+
.pipe(map$1(params => params.reduce((translatable, [param, value]) => `${translatable};${param}=${encodeSemicolons$1(value)}`, `%${key}`)), switchMap(translatable => Beans.get(WorkbenchTextService).text$(translatable, { provider })), map$1(text => text ?? key));
|
|
14389
14395
|
return toSignal(text$, { initialValue: '' });
|
|
14390
14396
|
}
|
|
14391
14397
|
/**
|
|
14392
|
-
*
|
|
14398
|
+
* Substitutes named parameters in a remote text.
|
|
14399
|
+
*/
|
|
14400
|
+
function interpolateRemoteText(translationKey, params) {
|
|
14401
|
+
// Test if the key matches a remote text.
|
|
14402
|
+
const match = REMOTE_TEXT.exec(translationKey);
|
|
14403
|
+
if (!match) {
|
|
14404
|
+
return undefined;
|
|
14405
|
+
}
|
|
14406
|
+
// Parse text and provider from the remote text.
|
|
14407
|
+
const { text, provider } = match.groups;
|
|
14408
|
+
// Substitute params. Parameters starting with the topic protocol 'topic://' are resolved via messaging.
|
|
14409
|
+
const text$ = observeParams$(params, { provider })
|
|
14410
|
+
.pipe(map$1(params => params.reduce((text, [param, value]) => text.replaceAll(`:${param}`, value), decodeSemicolons(text))));
|
|
14411
|
+
return toSignal(text$, { initialValue: '' });
|
|
14412
|
+
}
|
|
14413
|
+
/**
|
|
14414
|
+
* Creates an Observable that emits tuples of name-value pairs from the passed parameters.
|
|
14393
14415
|
*
|
|
14394
14416
|
* Parameters starting with the topic protocol 'topic://' are resolved via topic-based messaging.
|
|
14395
14417
|
*/
|
|
14396
|
-
function observeParams$(params) {
|
|
14397
|
-
const observableParams = Object.entries(params).map(([
|
|
14418
|
+
function observeParams$(params, options) {
|
|
14419
|
+
const observableParams = Object.entries(params).map(([param, value]) => {
|
|
14398
14420
|
if (!value.startsWith(TOPIC_PROTOCOL)) {
|
|
14399
|
-
return of([
|
|
14421
|
+
return of([param, value]);
|
|
14400
14422
|
}
|
|
14401
14423
|
const topic = value.substring(TOPIC_PROTOCOL.length);
|
|
14402
|
-
return Beans.get(MessageClient).request$(topic, undefined, { retain: true })
|
|
14424
|
+
return Beans.get(MessageClient).request$(topic, undefined, { retain: true })
|
|
14425
|
+
.pipe(mapToBody(),
|
|
14426
|
+
// Resolve text if the resolver returns a translatable.
|
|
14427
|
+
switchMap(resolved => resolved?.startsWith('%') ? Beans.get(WorkbenchTextService).text$(resolved, options) : of(resolved)), map$1(resolved => [param, resolved ?? '']));
|
|
14403
14428
|
});
|
|
14404
14429
|
return observableParams.length ? combineLatest(observableParams) : of([]);
|
|
14405
14430
|
}
|
|
@@ -14407,38 +14432,77 @@ function provideRemoteTextProvider() {
|
|
|
14407
14432
|
/**
|
|
14408
14433
|
* Creates a translatable for the SCION Workbench to request the text from a micro app.
|
|
14409
14434
|
*
|
|
14410
|
-
* Passed parameters are used to substitute named
|
|
14435
|
+
* Passed parameters are used to substitute named parameters in the text or interpolation parameters of the translation key.
|
|
14411
14436
|
*
|
|
14412
|
-
*
|
|
14437
|
+
* A named parameter starts with a colon (`:`) followed by the parameter name and can be substituted by an explicit value (passed as value param) or topic (passed as topic param).
|
|
14438
|
+
* Topic params define a topic with the actual value requested when resolving the translatable. A topic can also reference value params as named params in topic segments.
|
|
14413
14439
|
*
|
|
14414
|
-
*
|
|
14415
|
-
*
|
|
14416
|
-
*
|
|
14440
|
+
* @example - Translation Key
|
|
14441
|
+
* `%translationKey;param1=:namedParam1;param2=:namedParam2`
|
|
14442
|
+
*
|
|
14443
|
+
* @example - Text
|
|
14444
|
+
* `Text with :namedParam1 and :namedParam2`
|
|
14417
14445
|
*
|
|
14418
14446
|
* @param translatable - Specifies the translatable.
|
|
14419
|
-
* @param config - Specifies the text provider and values for substituting named
|
|
14447
|
+
* @param config - Specifies the text provider and values for substituting named parameters.
|
|
14420
14448
|
* @return Translatable that can be passed to the workbench's {@link text()} function for translation.
|
|
14421
14449
|
*
|
|
14422
14450
|
* @see provideRemoteTextProvider
|
|
14423
14451
|
*/
|
|
14424
14452
|
function createRemoteTranslatable(translatable, config) {
|
|
14425
|
-
if (!translatable
|
|
14453
|
+
if (!translatable) {
|
|
14454
|
+
return translatable;
|
|
14455
|
+
}
|
|
14456
|
+
// Create Map of value params.
|
|
14457
|
+
const valueParams = new Map(Object.entries(Dictionaries.coerce(config.valueParams)).map(([param, value]) => [param, encodeSemicolons$1(value)]));
|
|
14458
|
+
// Create Map of topic params, substituting referenced value params.
|
|
14459
|
+
const topicParams = new Map(Object.entries(Dictionaries.coerce(config.topicParams)).map(([param, topic]) => [param, toTopicParam(topic)]));
|
|
14460
|
+
// Return text as-is if not a translation key nor referencing parameters.
|
|
14461
|
+
if (!translatable.startsWith('%') && !containsParam(translatable, valueParams) && !containsParam(translatable, topicParams)) {
|
|
14426
14462
|
return translatable;
|
|
14427
14463
|
}
|
|
14428
|
-
const
|
|
14429
|
-
|
|
14430
|
-
|
|
14431
|
-
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14464
|
+
const remoteTranslatablePrefix = `%workbench.external.scion-workbench-client.${config.appSymbolicName}`;
|
|
14465
|
+
if (translatable.startsWith('%')) {
|
|
14466
|
+
// Substitute named parameters in interpolation params.
|
|
14467
|
+
return `${remoteTranslatablePrefix}.${translatable}`.replace(/(?<==):(?<namedParam>[^;]+)/g, (match, param) => valueParams.get(param) ?? topicParams.get(param) ?? match);
|
|
14468
|
+
}
|
|
14469
|
+
else {
|
|
14470
|
+
// Append referenced parameters in matrix notation.
|
|
14471
|
+
return [...valueParams, ...topicParams]
|
|
14472
|
+
.filter(([param]) => translatable.includes(`:${param}`))
|
|
14473
|
+
.reduce((translatable, [param, value]) => `${translatable};${param}=${value}`, `${remoteTranslatablePrefix}.${encodeSemicolons$1(translatable)}`);
|
|
14474
|
+
}
|
|
14475
|
+
/**
|
|
14476
|
+
* Adds the topic protocol to indicate resolution via topic-based messaging and substitutes named topic segments.
|
|
14477
|
+
*/
|
|
14478
|
+
function toTopicParam(topic) {
|
|
14479
|
+
return `${TOPIC_PROTOCOL}${topic.replace(/(?<=\/|^):(?<namedParam>[^/]+)/g, (match, namedParam) => {
|
|
14480
|
+
return valueParams.get(namedParam) ?? match;
|
|
14481
|
+
})}`;
|
|
14482
|
+
}
|
|
14483
|
+
/**
|
|
14484
|
+
* Tests whether the passed text references any of the passed params.
|
|
14485
|
+
*/
|
|
14486
|
+
function containsParam(text, params) {
|
|
14487
|
+
return Array.from(params.keys()).some(param => text.includes(`:${param}`));
|
|
14488
|
+
}
|
|
14437
14489
|
}
|
|
14438
14490
|
/**
|
|
14439
14491
|
* Prefix of topic params.
|
|
14440
14492
|
*/
|
|
14441
14493
|
const TOPIC_PROTOCOL = 'topic://';
|
|
14494
|
+
/**
|
|
14495
|
+
* Encodes semicolons (`;`) as `;` (Unicode) to prevent interpretation as interpolation parameter separators.
|
|
14496
|
+
*/
|
|
14497
|
+
function encodeSemicolons$1(value) {
|
|
14498
|
+
return `${value}`.replaceAll(';', ';');
|
|
14499
|
+
}
|
|
14500
|
+
/**
|
|
14501
|
+
* Decodes encoded semicolons (`;`) back to semicolons (`;`).
|
|
14502
|
+
*/
|
|
14503
|
+
function decodeSemicolons(value) {
|
|
14504
|
+
return value.replaceAll(';', ';');
|
|
14505
|
+
}
|
|
14442
14506
|
|
|
14443
14507
|
/*
|
|
14444
14508
|
* Copyright (c) 2018-2024 Swiss Federal Railways
|
|
@@ -17055,7 +17119,7 @@ function provideHostTextProvider() {
|
|
|
17055
17119
|
provideMicrofrontendPlatformInitializer(() => {
|
|
17056
17120
|
const injector = inject(Injector);
|
|
17057
17121
|
WorkbenchClient.registerTextProvider((key, params) => {
|
|
17058
|
-
const translatable = Object.entries(params).reduce((translatable, [name, value]) => `${translatable};${name}=${value}`, `%${key}`);
|
|
17122
|
+
const translatable = Object.entries(params).reduce((translatable, [name, value]) => `${translatable};${name}=${encodeSemicolons(value)}`, `%${key}`);
|
|
17059
17123
|
const environmentInjector = createEnvironmentInjector([], injector.get(EnvironmentInjector));
|
|
17060
17124
|
return toObservable(text(translatable, { injector: environmentInjector }), { injector: environmentInjector })
|
|
17061
17125
|
.pipe(map$1(text => text !== '' && text !== key ? text : undefined), // emit `undefined` if not found the text
|
|
@@ -17064,6 +17128,14 @@ function provideHostTextProvider() {
|
|
|
17064
17128
|
}),
|
|
17065
17129
|
]);
|
|
17066
17130
|
}
|
|
17131
|
+
/**
|
|
17132
|
+
* Encodes semicolons (`;`) as `\\;` to prevent interpretation as interpolation parameter separators.
|
|
17133
|
+
*
|
|
17134
|
+
* @see Translatable
|
|
17135
|
+
*/
|
|
17136
|
+
function encodeSemicolons(value) {
|
|
17137
|
+
return value.replaceAll(';', '\\;');
|
|
17138
|
+
}
|
|
17067
17139
|
|
|
17068
17140
|
/*
|
|
17069
17141
|
* Copyright (c) 2018-2024 Swiss Federal Railways
|