@praxisui/core 9.0.37 → 9.0.39

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.
@@ -3644,7 +3644,8 @@ class ApiConfigStorage {
3644
3644
  return resolved.trim();
3645
3645
  return this.inferComponentType(key);
3646
3646
  };
3647
- // Simple in-memory cache of etag/payload per key to support 304 reuse
3647
+ // Keep read/write validators separate: weak ETags can revalidate GETs but
3648
+ // cannot satisfy If-Match for governed writes.
3648
3649
  cache = new Map();
3649
3650
  constructor() { }
3650
3651
  shouldLogLoadError(key, err) {
@@ -3671,7 +3672,7 @@ class ApiConfigStorage {
3671
3672
  }
3672
3673
  executeLoadConfigRequest(key, establishAvailability) {
3673
3674
  const cached = this.cache.get(key);
3674
- const etag = cached?.etag;
3675
+ const etag = cached?.readEtag ?? cached?.writeEtag;
3675
3676
  const { type, id } = this.resolveKey(key);
3676
3677
  const url = `${this.baseUrl}`;
3677
3678
  const params = this.buildParams(type, id, cached?.scope);
@@ -3694,11 +3695,14 @@ class ApiConfigStorage {
3694
3695
  return this.http
3695
3696
  .get(url, { observe: 'response', headers, params })
3696
3697
  .pipe(map((resp) => {
3697
- const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
3698
3698
  const body = resp.body;
3699
- if (nextEtag) {
3699
+ const responseEtag = resp.headers.get('ETag');
3700
+ const readEtag = this.resolveReadEtag(responseEtag, body?.etag);
3701
+ const writeEtag = this.resolveWriteEtag(responseEtag, body?.etag);
3702
+ if (readEtag || writeEtag) {
3700
3703
  this.cache.set(key, {
3701
- etag: nextEtag,
3704
+ readEtag,
3705
+ writeEtag,
3702
3706
  payload: body?.payload,
3703
3707
  scope: this.resolveResponseScope(body?.scope),
3704
3708
  });
@@ -3726,11 +3730,14 @@ class ApiConfigStorage {
3726
3730
  return this.http
3727
3731
  .get(url, { observe: 'response', headers, params })
3728
3732
  .pipe(map((resp) => {
3729
- const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
3730
3733
  const body = resp.body;
3731
- if (nextEtag) {
3734
+ const responseEtag = resp.headers.get('ETag');
3735
+ const readEtag = this.resolveReadEtag(responseEtag, body?.etag);
3736
+ const writeEtag = this.resolveWriteEtag(responseEtag, body?.etag);
3737
+ if (readEtag || writeEtag) {
3732
3738
  this.cache.set(key, {
3733
- etag: nextEtag,
3739
+ readEtag,
3740
+ writeEtag,
3734
3741
  payload: body?.payload,
3735
3742
  scope: this.resolveResponseScope(body?.scope),
3736
3743
  });
@@ -3757,16 +3764,20 @@ class ApiConfigStorage {
3757
3764
  const url = `${this.baseUrl}`;
3758
3765
  const cached = this.cache.get(key);
3759
3766
  const params = this.buildParams(type, id, cached?.scope);
3760
- const headers = this.buildHeaders(cached?.etag ? { 'If-Match': this.formatEtag(cached.etag) } : undefined);
3767
+ const headers = this.buildHeaders(cached?.writeEtag
3768
+ ? { 'If-Match': this.formatEtag(cached.writeEtag) }
3769
+ : undefined);
3761
3770
  return this.http
3762
3771
  .put(url, { payload: config }, { observe: 'response', headers, params })
3763
3772
  .pipe(map((resp) => {
3764
- const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
3765
- const payload = resp.body?.payload ?? config;
3773
+ const body = resp.body;
3774
+ const responseEtag = resp.headers.get('ETag');
3775
+ const payload = body?.payload ?? config;
3766
3776
  this.cache.set(key, {
3767
- etag: nextEtag,
3777
+ readEtag: this.resolveReadEtag(responseEtag, body?.etag),
3778
+ writeEtag: this.resolveWriteEtag(responseEtag, body?.etag),
3768
3779
  payload,
3769
- scope: this.resolveResponseScope(resp.body?.scope) ?? cached?.scope,
3780
+ scope: this.resolveResponseScope(body?.scope) ?? cached?.scope,
3770
3781
  });
3771
3782
  }), catchError((err) => {
3772
3783
  if (this.shouldLogSaveError(key, err)) {
@@ -3799,18 +3810,22 @@ class ApiConfigStorage {
3799
3810
  shouldPropagateLoadError(key, _err) {
3800
3811
  if (this.opts?.errorPolicy !== 'fail')
3801
3812
  return false;
3802
- return key.startsWith('praxis:global-config');
3813
+ return (key.startsWith('praxis:global-config')
3814
+ || key.startsWith('dynamic-page:'));
3803
3815
  }
3804
3816
  isCriticalPersistenceKey(key) {
3805
3817
  return (key.startsWith('praxis:global-config')
3806
- || key.startsWith('table-config:'));
3818
+ || key.startsWith('table-config:')
3819
+ || key.startsWith('dynamic-page:'));
3807
3820
  }
3808
3821
  clearConfig(key) {
3809
3822
  const { type, id } = this.resolveKey(key);
3810
3823
  const url = `${this.baseUrl}`;
3811
3824
  const cached = this.cache.get(key);
3812
3825
  const params = this.buildParams(type, id, cached?.scope);
3813
- const headers = this.buildHeaders(cached?.etag ? { 'If-Match': this.formatEtag(cached.etag) } : undefined);
3826
+ const headers = this.buildHeaders(cached?.writeEtag
3827
+ ? { 'If-Match': this.formatEtag(cached.writeEtag) }
3828
+ : undefined);
3814
3829
  return this.http
3815
3830
  .delete(url, { observe: 'response', headers, params })
3816
3831
  .pipe(map(() => {
@@ -3922,19 +3937,35 @@ class ApiConfigStorage {
3922
3937
  const parts = value.split(':');
3923
3938
  return (parts.length === 4 || parts.length === 5) && !parts[0].includes('/');
3924
3939
  }
3925
- stripQuotes(value) {
3926
- if (!value)
3940
+ resolveReadEtag(responseHeader, responseBodyEtag) {
3941
+ const header = responseHeader?.trim();
3942
+ if (header)
3943
+ return header;
3944
+ return this.resolveWriteEtag(null, responseBodyEtag);
3945
+ }
3946
+ resolveWriteEtag(responseHeader, responseBodyEtag) {
3947
+ const bodyEtag = this.normalizeStrongEtag(responseBodyEtag);
3948
+ if (bodyEtag)
3949
+ return bodyEtag;
3950
+ return this.normalizeStrongEtag(responseHeader);
3951
+ }
3952
+ normalizeStrongEtag(value) {
3953
+ if (typeof value !== 'string')
3954
+ return null;
3955
+ const normalized = value.trim();
3956
+ if (!normalized || normalized.startsWith('W/'))
3927
3957
  return null;
3928
- const v = value.trim();
3929
- if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) {
3930
- return v.substring(1, v.length - 1);
3958
+ if (normalized.startsWith('"')
3959
+ && normalized.endsWith('"')
3960
+ && normalized.length >= 2) {
3961
+ return normalized.substring(1, normalized.length - 1);
3931
3962
  }
3932
- return v;
3963
+ return normalized;
3933
3964
  }
3934
3965
  formatEtag(etag) {
3935
3966
  if (!etag)
3936
3967
  return undefined;
3937
- return etag.startsWith('"') ? etag : `"${etag}"`;
3968
+ return etag.startsWith('"') || etag.startsWith('W/') ? etag : `"${etag}"`;
3938
3969
  }
3939
3970
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ApiConfigStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3940
3971
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ApiConfigStorage, providedIn: 'root' });
@@ -8501,6 +8532,45 @@ function validateGlobalActionRefs(targets) {
8501
8532
  return targets.flatMap((target) => validateGlobalActionRef(target.ref, target.catalogEntry, target.path));
8502
8533
  }
8503
8534
 
8535
+ const PRAXIS_GLOBAL_ACTION_PROVIDER_EVIDENCE = Symbol.for('@praxisui/core/global-action-provider-evidence');
8536
+ /**
8537
+ * Binds an adapter created by an official host/provider factory to the exact
8538
+ * actions that factory can serve. This is non-executing runtime evidence; it
8539
+ * does not invoke the adapter and is not a security boundary.
8540
+ */
8541
+ function markGlobalActionProviderOperational(adapter, evidence) {
8542
+ const normalized = Object.freeze({
8543
+ providerId: evidence.providerId.trim(),
8544
+ actionIds: Object.freeze(Array.from(new Set(evidence.actionIds.map((actionId) => actionId.trim()).filter(Boolean))).sort()),
8545
+ scope: 'host-adapter',
8546
+ });
8547
+ Object.defineProperty(adapter, PRAXIS_GLOBAL_ACTION_PROVIDER_EVIDENCE, {
8548
+ configurable: false,
8549
+ enumerable: false,
8550
+ writable: false,
8551
+ value: normalized,
8552
+ });
8553
+ return adapter;
8554
+ }
8555
+ function getGlobalActionProviderEvidence(adapter) {
8556
+ if (!adapter || (typeof adapter !== 'object' && typeof adapter !== 'function')) {
8557
+ return null;
8558
+ }
8559
+ const evidence = adapter[PRAXIS_GLOBAL_ACTION_PROVIDER_EVIDENCE];
8560
+ if (!evidence
8561
+ || evidence.scope !== 'host-adapter'
8562
+ || typeof evidence.providerId !== 'string'
8563
+ || !evidence.providerId.trim()
8564
+ || !Array.isArray(evidence.actionIds)
8565
+ || !evidence.actionIds.every((actionId) => typeof actionId === 'string' && !!actionId.trim())) {
8566
+ return null;
8567
+ }
8568
+ return evidence;
8569
+ }
8570
+ function isGlobalActionProviderOperational(adapter, actionId) {
8571
+ return getGlobalActionProviderEvidence(adapter)?.actionIds.includes(actionId) === true;
8572
+ }
8573
+
8504
8574
  const SURFACE_NAVIGATION_I18N_NAMESPACE = 'surfaceNavigation';
8505
8575
  const SURFACE_NAVIGATION_I18N_CONFIG = {
8506
8576
  namespaces: {
@@ -8571,6 +8641,8 @@ const SURFACE_DRAWER_CONTENT_DATA = new InjectionToken('SURFACE_DRAWER_CONTENT_D
8571
8641
 
8572
8642
  class GlobalActionService {
8573
8643
  handlers = new Map();
8644
+ readinessProbes = new Map();
8645
+ selfContainedReadiness = new Set();
8574
8646
  router = (() => { try {
8575
8647
  return inject(Router);
8576
8648
  }
@@ -8605,17 +8677,57 @@ class GlobalActionService {
8605
8677
  i18n = inject(PraxisI18nService);
8606
8678
  constructor() {
8607
8679
  const entries = inject(GLOBAL_ACTION_HANDLERS, { optional: true });
8608
- (entries || []).forEach((e) => this.register(e.id, e.handler));
8680
+ (entries || []).forEach((e) => this.register(e.id, e.handler, e.readiness));
8609
8681
  this.registerBuiltins();
8610
8682
  }
8611
- register(id, handler) {
8683
+ register(id, handler, readiness) {
8612
8684
  if (!id || !handler)
8613
8685
  return;
8614
8686
  this.handlers.set(id, handler);
8687
+ if (readiness) {
8688
+ this.readinessProbes.set(id, readiness);
8689
+ }
8690
+ else {
8691
+ this.readinessProbes.delete(id);
8692
+ }
8615
8693
  }
8616
8694
  has(id) {
8617
8695
  return this.handlers.has(id);
8618
8696
  }
8697
+ /**
8698
+ * Proves that a registered action can be invoked in the supplied runtime
8699
+ * context without executing its side effect.
8700
+ */
8701
+ getReadiness(id, context) {
8702
+ const handlerRequirement = this.requirement('handler', id, this.handlers.has(id));
8703
+ if (!handlerRequirement.satisfied) {
8704
+ return { ready: false, scope: 'host', requirements: [handlerRequirement] };
8705
+ }
8706
+ const probe = this.readinessProbes.get(id);
8707
+ let requirements = [];
8708
+ if (!probe) {
8709
+ requirements = [this.requirement('provider', 'readiness-probe', false)];
8710
+ }
8711
+ else
8712
+ try {
8713
+ const probed = probe(context);
8714
+ requirements = this.isValidReadinessRequirements(probed)
8715
+ && (probed.length > 0 || this.selfContainedReadiness.has(id))
8716
+ ? probed
8717
+ : [this.requirement('provider', 'readiness-probe-invalid', false)];
8718
+ }
8719
+ catch {
8720
+ requirements = [this.requirement('runtime-context', 'readiness-probe', false)];
8721
+ }
8722
+ const all = [handlerRequirement, ...requirements];
8723
+ return {
8724
+ ready: all.every((requirement) => requirement.satisfied),
8725
+ scope: all.some((requirement) => requirement.kind === 'runtime-context')
8726
+ ? 'context'
8727
+ : 'host',
8728
+ requirements: all,
8729
+ };
8730
+ }
8619
8731
  async execute(id, payload, context) {
8620
8732
  const handler = this.handlers.get(id);
8621
8733
  if (!handler) {
@@ -8716,7 +8828,7 @@ class GlobalActionService {
8716
8828
  return { success: true };
8717
8829
  }
8718
8830
  return { success: false, error: 'History not available' };
8719
- });
8831
+ }, () => [this.requirement('platform-api', 'navigation-history', !!this.location || (typeof window !== 'undefined' && !!window.history))]);
8720
8832
  this.register('navigation.openExternal', async (payload) => {
8721
8833
  const url = payload?.url || payload?.href || payload;
8722
8834
  if (!url)
@@ -8726,32 +8838,32 @@ class GlobalActionService {
8726
8838
  return { success: true };
8727
8839
  }
8728
8840
  return { success: false, error: 'Window not available' };
8729
- });
8730
- this.register('navigation.openRoute', async (payload) => this.handleNavigationOpenRoute(payload));
8841
+ }, () => [this.requirement('platform-api', 'window.open', typeof window !== 'undefined')]);
8842
+ this.register('navigation.openRoute', async (payload) => this.handleNavigationOpenRoute(payload), () => [this.requirement('platform-api', 'Router|window.location', !!this.router || (typeof window !== 'undefined' && !!window.location))]);
8731
8843
  this.register('dialog.alert', async (payload) => {
8732
8844
  if (!this.dialog)
8733
8845
  return { success: false, error: 'Dialog service not available' };
8734
8846
  await this.dialog.alert(payload || {});
8735
8847
  return { success: true };
8736
- });
8848
+ }, () => [this.providerRequirement('GLOBAL_DIALOG_SERVICE', this.dialog, 'dialog.alert')]);
8737
8849
  this.register('dialog.confirm', async (payload) => {
8738
8850
  if (!this.dialog)
8739
8851
  return { success: false, error: 'Dialog service not available' };
8740
8852
  const data = await this.dialog.confirm(payload || {});
8741
8853
  return { success: true, data: !!data };
8742
- });
8854
+ }, () => [this.providerRequirement('GLOBAL_DIALOG_SERVICE', this.dialog, 'dialog.confirm')]);
8743
8855
  this.register('dialog.prompt', async (payload) => {
8744
8856
  if (!this.dialog)
8745
8857
  return { success: false, error: 'Dialog service not available' };
8746
8858
  const data = await this.dialog.prompt(payload || {});
8747
8859
  return { success: true, data };
8748
- });
8860
+ }, () => [this.providerRequirement('GLOBAL_DIALOG_SERVICE', this.dialog, 'dialog.prompt')]);
8749
8861
  this.register('dialog.open', async (payload) => {
8750
8862
  if (!this.dialog)
8751
8863
  return { success: false, error: 'Dialog service not available' };
8752
8864
  const data = await this.dialog.open(payload || {});
8753
8865
  return { success: true, data };
8754
- });
8866
+ }, () => [this.providerRequirement('GLOBAL_DIALOG_SERVICE', this.dialog, 'dialog.open')]);
8755
8867
  this.register('surface.open', async (payload, context) => {
8756
8868
  if (!this.surface)
8757
8869
  return { success: false, error: 'Surface service not available' };
@@ -8763,7 +8875,7 @@ class GlobalActionService {
8763
8875
  const data = await this.surface.open(resolvedPayload, context);
8764
8876
  this.bindSurfaceResultAction(data, resolvedPayload, context);
8765
8877
  return { success: true, data };
8766
- });
8878
+ }, () => [this.providerRequirement('GLOBAL_SURFACE_SERVICE', this.surface, 'surface.open')]);
8767
8879
  this.register('surface.close', async (payload, context) => {
8768
8880
  const runtime = this.resolveSurfaceRuntime(context);
8769
8881
  if (typeof runtime?.close !== 'function') {
@@ -8771,7 +8883,7 @@ class GlobalActionService {
8771
8883
  }
8772
8884
  runtime.close(this.toSurfaceResult(payload, 'close'));
8773
8885
  return { success: true };
8774
- });
8886
+ }, (context) => [this.requirement('runtime-context', 'surface.close', typeof this.resolveSurfaceRuntime(context)?.close === 'function')]);
8775
8887
  this.register('surface.result', async (payload, context) => {
8776
8888
  const runtime = this.resolveSurfaceRuntime(context);
8777
8889
  if (typeof runtime?.emitResult !== 'function') {
@@ -8779,7 +8891,7 @@ class GlobalActionService {
8779
8891
  }
8780
8892
  runtime.emitResult(this.toSurfaceResult(payload, 'result'));
8781
8893
  return { success: true };
8782
- });
8894
+ }, (context) => [this.requirement('runtime-context', 'surface.emitResult', typeof this.resolveSurfaceRuntime(context)?.emitResult === 'function')]);
8783
8895
  this.register('surface.complete', async (payload, context) => {
8784
8896
  const runtime = this.resolveSurfaceRuntime(context);
8785
8897
  if (typeof runtime?.complete !== 'function') {
@@ -8787,8 +8899,8 @@ class GlobalActionService {
8787
8899
  }
8788
8900
  runtime.complete(this.toSurfaceOutcome(payload));
8789
8901
  return { success: true };
8790
- });
8791
- this.register('dynamicPage.composition.dispatch', async (payload, context) => this.handleCompositionDispatch(payload, context));
8902
+ }, (context) => [this.requirement('runtime-context', 'surface.complete', typeof this.resolveSurfaceRuntime(context)?.complete === 'function')]);
8903
+ this.register('dynamicPage.composition.dispatch', async (payload, context) => this.handleCompositionDispatch(payload, context), (context) => [this.requirement('runtime-context', 'composition.dispatch', typeof context?.runtime?.composition?.dispatch === 'function')]);
8792
8904
  this.register('toast.success', async (payload) => {
8793
8905
  const message = payload?.message || payload;
8794
8906
  if (!message)
@@ -8797,7 +8909,7 @@ class GlobalActionService {
8797
8909
  return { success: false, error: 'Toast service not available' };
8798
8910
  this.toast.success(message, payload);
8799
8911
  return { success: true };
8800
- });
8912
+ }, () => [this.providerRequirement('GLOBAL_TOAST_SERVICE', this.toast, 'toast.success')]);
8801
8913
  this.register('toast.error', async (payload) => {
8802
8914
  const message = payload?.message || payload;
8803
8915
  if (!message)
@@ -8806,7 +8918,7 @@ class GlobalActionService {
8806
8918
  return { success: false, error: 'Toast service not available' };
8807
8919
  this.toast.error(message, payload);
8808
8920
  return { success: true };
8809
- });
8921
+ }, () => [this.providerRequirement('GLOBAL_TOAST_SERVICE', this.toast, 'toast.error')]);
8810
8922
  this.register('clipboard.copy', async (payload) => {
8811
8923
  const text = payload?.text ?? payload?.value ?? payload;
8812
8924
  if (text == null)
@@ -8818,7 +8930,7 @@ class GlobalActionService {
8818
8930
  catch {
8819
8931
  return { success: false, error: 'Clipboard not available' };
8820
8932
  }
8821
- });
8933
+ }, () => [this.requirement('platform-api', 'navigator.clipboard.writeText', typeof navigator !== 'undefined' && typeof navigator.clipboard?.writeText === 'function')]);
8822
8934
  this.register('trackEvent', async (payload) => {
8823
8935
  const eventName = payload?.eventName || payload?.name;
8824
8936
  if (!eventName)
@@ -8827,7 +8939,7 @@ class GlobalActionService {
8827
8939
  return { success: false, error: 'Analytics service not available' };
8828
8940
  this.analytics.track(eventName, payload?.payload ?? payload?.data);
8829
8941
  return { success: true };
8830
- });
8942
+ }, () => [this.providerRequirement('GLOBAL_ANALYTICS_SERVICE', this.analytics, 'trackEvent')]);
8831
8943
  this.register('log', async (payload) => {
8832
8944
  const level = payload?.level || 'info';
8833
8945
  const message = payload?.message || '';
@@ -8835,11 +8947,33 @@ class GlobalActionService {
8835
8947
  const fn = console[level] || console.log;
8836
8948
  fn('[GlobalAction]', message, data ?? payload);
8837
8949
  return { success: true };
8838
- });
8839
- this.register('api.get', async (payload) => this.handleApi('get', payload));
8840
- this.register('api.post', async (payload) => this.handleApi('post', payload));
8841
- this.register('api.patch', async (payload) => this.handleApi('patch', payload));
8842
- this.register('route.register', async (payload) => this.handleRouteRegister(payload));
8950
+ }, () => []);
8951
+ this.selfContainedReadiness.add('log');
8952
+ this.register('api.get', async (payload) => this.handleApi('get', payload), () => [
8953
+ this.providerRequirement('GLOBAL_API_CLIENT', this.api, 'api.get'),
8954
+ ]);
8955
+ this.register('api.post', async (payload) => this.handleApi('post', payload), () => [
8956
+ this.providerRequirement('GLOBAL_API_CLIENT', this.api, 'api.post'),
8957
+ ]);
8958
+ this.register('api.patch', async (payload) => this.handleApi('patch', payload), () => [
8959
+ this.providerRequirement('GLOBAL_API_CLIENT', this.api, 'api.patch'),
8960
+ ]);
8961
+ this.register('route.register', async (payload) => this.handleRouteRegister(payload), () => [this.requirement('provider', 'Router', !!this.router)]);
8962
+ }
8963
+ requirement(kind, id, satisfied) {
8964
+ return { kind, id, satisfied };
8965
+ }
8966
+ providerRequirement(providerId, adapter, actionId) {
8967
+ return this.requirement('provider', providerId, isGlobalActionProviderOperational(adapter, actionId));
8968
+ }
8969
+ isValidReadinessRequirements(value) {
8970
+ return Array.isArray(value)
8971
+ && value.every((requirement) => !!requirement
8972
+ && typeof requirement === 'object'
8973
+ && ['handler', 'provider', 'runtime-context', 'platform-api'].includes(requirement.kind)
8974
+ && typeof requirement.id === 'string'
8975
+ && !!requirement.id.trim()
8976
+ && typeof requirement.satisfied === 'boolean');
8843
8977
  }
8844
8978
  async handleApi(method, payload) {
8845
8979
  if (!this.api)
@@ -12747,9 +12881,8 @@ function rotr(value, amount) {
12747
12881
  return (value >>> amount) | (value << (32 - amount));
12748
12882
  }
12749
12883
 
12750
- const PRAXIS_TELEMETRY_TRANSPORT = new InjectionToken('PRAXIS_TELEMETRY_TRANSPORT', {
12751
- providedIn: 'root',
12752
- factory: () => ({
12884
+ function defaultTelemetryTransport() {
12885
+ return {
12753
12886
  emit: (event) => {
12754
12887
  try {
12755
12888
  (console.log || console.info)('[Telemetry]', event);
@@ -12758,7 +12891,11 @@ const PRAXIS_TELEMETRY_TRANSPORT = new InjectionToken('PRAXIS_TELEMETRY_TRANSPOR
12758
12891
  // Telemetry transport must never break runtime.
12759
12892
  }
12760
12893
  },
12761
- }),
12894
+ };
12895
+ }
12896
+ const PRAXIS_TELEMETRY_TRANSPORT = new InjectionToken('PRAXIS_TELEMETRY_TRANSPORT', {
12897
+ providedIn: 'root',
12898
+ factory: defaultTelemetryTransport,
12762
12899
  });
12763
12900
  class TelemetryService {
12764
12901
  transport = inject(PRAXIS_TELEMETRY_TRANSPORT);
@@ -12789,6 +12926,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
12789
12926
  type: Injectable,
12790
12927
  args: [{ providedIn: 'root' }]
12791
12928
  }] });
12929
+ /** Explicit bootstrap for isolated EnvironmentInjectors and host applications. */
12930
+ function providePraxisTelemetry(transport) {
12931
+ return [
12932
+ {
12933
+ provide: PRAXIS_TELEMETRY_TRANSPORT,
12934
+ useFactory: () => transport ?? defaultTelemetryTransport(),
12935
+ },
12936
+ TelemetryService,
12937
+ ];
12938
+ }
12792
12939
 
12793
12940
  const PRAXIS_EXPORT_FORMULA_PREFIXES = ['=', '+', '-', '@', '\t', '\r'];
12794
12941
  const PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY = {
@@ -18092,7 +18239,7 @@ function providePraxisToastGlobalActions(opts = {}) {
18092
18239
  const errorDuration = opts.errorDurationMs ?? 3500;
18093
18240
  const successClass = opts.successPanelClass ?? ['pdx-toast-success'];
18094
18241
  const errorClass = opts.errorPanelClass ?? ['pdx-toast-error'];
18095
- return {
18242
+ const adapter = {
18096
18243
  success: (message) => {
18097
18244
  if (snack) {
18098
18245
  snack.open(message, undefined, { duration: successDuration, panelClass: successClass });
@@ -18110,6 +18257,13 @@ function providePraxisToastGlobalActions(opts = {}) {
18110
18257
  }
18111
18258
  },
18112
18259
  };
18260
+ return snack
18261
+ ? markGlobalActionProviderOperational(adapter, {
18262
+ providerId: 'providePraxisToastGlobalActions:MatSnackBar',
18263
+ actionIds: ['toast.success', 'toast.error'],
18264
+ scope: 'host-adapter',
18265
+ })
18266
+ : adapter;
18113
18267
  },
18114
18268
  };
18115
18269
  }
@@ -18125,7 +18279,7 @@ function providePraxisAnalyticsGlobalActions(opts = {}) {
18125
18279
  return null;
18126
18280
  } })();
18127
18281
  const prefix = opts.prefix ? `${opts.prefix}.` : '';
18128
- return {
18282
+ const adapter = {
18129
18283
  track: (eventName, payload) => {
18130
18284
  if (telemetry) {
18131
18285
  telemetry.record(`${prefix}${eventName}`, payload);
@@ -18135,6 +18289,13 @@ function providePraxisAnalyticsGlobalActions(opts = {}) {
18135
18289
  }
18136
18290
  },
18137
18291
  };
18292
+ return telemetry
18293
+ ? markGlobalActionProviderOperational(adapter, {
18294
+ providerId: 'providePraxisAnalyticsGlobalActions:TelemetryService',
18295
+ actionIds: ['trackEvent'],
18296
+ scope: 'host-adapter',
18297
+ })
18298
+ : adapter;
18138
18299
  },
18139
18300
  };
18140
18301
  }
@@ -19781,7 +19942,13 @@ function providePraxisGlobalActions(opts = {
19781
19942
  console.error('[Toast]', message);
19782
19943
  },
19783
19944
  };
19784
- return fallback;
19945
+ return snack
19946
+ ? markGlobalActionProviderOperational(fallback, {
19947
+ providerId: 'providePraxisGlobalActions:MatSnackBar',
19948
+ actionIds: ['toast.success', 'toast.error'],
19949
+ scope: 'host-adapter',
19950
+ })
19951
+ : fallback;
19785
19952
  },
19786
19953
  });
19787
19954
  }
@@ -31350,7 +31517,9 @@ class PraxisRichTextBlockComponent {
31350
31517
  contentFormat = 'plain';
31351
31518
  content = '';
31352
31519
  get renderedContent() {
31353
- const format = isAllowedEditorialContentFormat(this.contentFormat) ? this.contentFormat : 'plain';
31520
+ const format = isAllowedEditorialContentFormat(this.contentFormat)
31521
+ ? this.contentFormat
31522
+ : 'plain';
31354
31523
  const html = format === 'markdown'
31355
31524
  ? renderEditorialMarkdown(this.content)
31356
31525
  : renderEditorialPlain(this.content);
@@ -31363,11 +31532,15 @@ class PraxisRichTextBlockComponent {
31363
31532
  [class.prt-block-emphasis]="variant === 'emphasis'"
31364
31533
  [class.prt-block-subtle]="variant === 'subtle'"
31365
31534
  [class.prt-block-plain]="appearance === 'plain'"
31366
- >
31535
+ >
31367
31536
  @if (icon || title || subtitle) {
31368
31537
  <header class="prt-head">
31369
31538
  @if (icon) {
31370
- <mat-icon class="prt-icon" aria-hidden="true" [praxisIcon]="icon"></mat-icon>
31539
+ <mat-icon
31540
+ class="prt-icon"
31541
+ aria-hidden="true"
31542
+ [praxisIcon]="icon"
31543
+ ></mat-icon>
31371
31544
  }
31372
31545
  <div class="prt-title-wrap">
31373
31546
  @if (title) {
@@ -31379,15 +31552,15 @@ class PraxisRichTextBlockComponent {
31379
31552
  </div>
31380
31553
  </header>
31381
31554
  }
31382
-
31555
+
31383
31556
  <div class="prt-content" [innerHTML]="renderedContent"></div>
31384
31557
  </section>
31385
- `, isInline: true, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31558
+ `, isInline: true, styles: [":host{display:block;min-width:0;max-width:100%;--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 72%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4% ), color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64% ), color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 82%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 64%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent )}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 84%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ), color-mix( in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72% ), color-mix( in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 88%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 42%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-high) 88%, transparent )}.prt-block{display:grid;min-width:0;max-width:100%;box-sizing:border-box;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;min-width:0;gap:4px}.prt-title,.prt-subtitle,.prt-content{overflow-wrap:anywhere}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31386
31559
  }
31387
31560
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisRichTextBlockComponent, decorators: [{
31388
31561
  type: Component,
31389
31562
  args: [{ selector: 'praxis-rich-text-block', standalone: true, imports: [MatIconModule, PraxisIconDirective], host: {
31390
- 'class': 'praxis-rich-text-block',
31563
+ class: 'praxis-rich-text-block',
31391
31564
  '[attr.data-instance-id]': 'instanceId || null',
31392
31565
  '[attr.data-analytics-id]': 'analyticsId || null',
31393
31566
  '[attr.data-variant]': 'variant',
@@ -31399,11 +31572,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
31399
31572
  [class.prt-block-emphasis]="variant === 'emphasis'"
31400
31573
  [class.prt-block-subtle]="variant === 'subtle'"
31401
31574
  [class.prt-block-plain]="appearance === 'plain'"
31402
- >
31575
+ >
31403
31576
  @if (icon || title || subtitle) {
31404
31577
  <header class="prt-head">
31405
31578
  @if (icon) {
31406
- <mat-icon class="prt-icon" aria-hidden="true" [praxisIcon]="icon"></mat-icon>
31579
+ <mat-icon
31580
+ class="prt-icon"
31581
+ aria-hidden="true"
31582
+ [praxisIcon]="icon"
31583
+ ></mat-icon>
31407
31584
  }
31408
31585
  <div class="prt-title-wrap">
31409
31586
  @if (title) {
@@ -31415,10 +31592,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
31415
31592
  </div>
31416
31593
  </header>
31417
31594
  }
31418
-
31595
+
31419
31596
  <div class="prt-content" [innerHTML]="renderedContent"></div>
31420
31597
  </section>
31421
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"] }]
31598
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;min-width:0;max-width:100%;--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 72%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4% ), color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64% ), color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 82%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 64%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent )}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 84%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ), color-mix( in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72% ), color-mix( in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 88%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 42%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-high) 88%, transparent )}.prt-block{display:grid;min-width:0;max-width:100%;box-sizing:border-box;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;min-width:0;gap:4px}.prt-title,.prt-subtitle,.prt-content{overflow-wrap:anywhere}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"] }]
31422
31599
  }], propDecorators: { instanceId: [{
31423
31600
  type: Input
31424
31601
  }], analyticsId: [{
@@ -31492,7 +31669,9 @@ function renderInlineMarkdown(text) {
31492
31669
  if (!normalized) {
31493
31670
  return escapeHtml(decodeHtml(label));
31494
31671
  }
31495
- const target = normalized.target ? ` target="${escapeHtml(normalized.target)}"` : '';
31672
+ const target = normalized.target
31673
+ ? ` target="${escapeHtml(normalized.target)}"`
31674
+ : '';
31496
31675
  const rel = normalized.rel || EDITORIAL_EXTERNAL_LINK_REL;
31497
31676
  return reserve(`<a href="${escapeHtml(normalized.href)}"${target} rel="${escapeHtml(rel)}">${escapeHtml(normalized.label)}</a>`);
31498
31677
  });
@@ -31523,7 +31702,7 @@ function decodeHtml(value) {
31523
31702
  .replace(/&lt;/g, '<')
31524
31703
  .replace(/&gt;/g, '>')
31525
31704
  .replace(/&quot;/g, '"')
31526
- .replace(/&#39;/g, '\'')
31705
+ .replace(/&#39;/g, "'")
31527
31706
  .replace(/&amp;/g, '&');
31528
31707
  }
31529
31708
 
@@ -32902,7 +33081,11 @@ class WidgetShellComponent {
32902
33081
  return false;
32903
33082
  if (this.shell?.showHeader != null)
32904
33083
  return !!this.shell.showHeader;
32905
- return !!(this.shell?.title || this.shell?.subtitle || this.shell?.icon || this.headerActions.length || this.windowActions.length);
33084
+ return !!(this.shell?.title ||
33085
+ this.shell?.subtitle ||
33086
+ this.shell?.icon ||
33087
+ this.headerActions.length ||
33088
+ this.windowActions.length);
32906
33089
  }
32907
33090
  get headerActions() {
32908
33091
  return (this.shell?.actions || []).filter((a) => this.isVisible(a) && (a.placement || 'header') === 'header');
@@ -32950,13 +33133,15 @@ class WidgetShellComponent {
32950
33133
  this.action.emit(event);
32951
33134
  }
32952
33135
  onHeaderPointerDown(event) {
32953
- if (!this.dragSurfaceInteractive || this.isInteractiveHeaderTarget(event.target)) {
33136
+ if (!this.dragSurfaceInteractive ||
33137
+ this.isInteractiveHeaderTarget(event.target)) {
32954
33138
  return;
32955
33139
  }
32956
33140
  this.dragSurfacePointerDown.emit(event);
32957
33141
  }
32958
33142
  onHeaderKeydown(event) {
32959
- if (!this.dragSurfaceInteractive || this.isInteractiveHeaderTarget(event.target)) {
33143
+ if (!this.dragSurfaceInteractive ||
33144
+ this.isInteractiveHeaderTarget(event.target)) {
32960
33145
  return;
32961
33146
  }
32962
33147
  this.dragSurfaceKeydown.emit(event);
@@ -33038,7 +33223,7 @@ class WidgetShellComponent {
33038
33223
  if (!presetId)
33039
33224
  return undefined;
33040
33225
  const ctxPresets = this.context?.ui?.shell?.presets || {};
33041
- return (ctxPresets && ctxPresets[presetId]) || BUILTIN_SHELL_PRESETS[presetId];
33226
+ return ((ctxPresets && ctxPresets[presetId]) || BUILTIN_SHELL_PRESETS[presetId]);
33042
33227
  }
33043
33228
  mergeAppearance(base, override) {
33044
33229
  if (!base && !override)
@@ -33080,294 +33265,378 @@ class WidgetShellComponent {
33080
33265
  }
33081
33266
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33082
33267
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: WidgetShellComponent, isStandalone: true, selector: "praxis-widget-shell", inputs: { shell: "shell", context: "context", dragSurfaceEnabled: "dragSurfaceEnabled", dragSurfaceLabel: "dragSurfaceLabel" }, outputs: { action: "action", dragSurfacePointerDown: "dragSurfacePointerDown", dragSurfaceKeydown: "dragSurfaceKeydown" }, host: { properties: { "class.pdx-widget-shell-collapsed": "this.hostCollapsed" } }, providers: [providePraxisI18nConfig(WIDGET_SHELL_I18N_CONFIG)], queries: [{ propertyName: "loader", first: true, predicate: DynamicWidgetLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
33083
- <section
33084
- class="pdx-shell"
33085
- [class.no-shell]="!shellEnabled"
33086
- [class.dashboard]="shellEnabled"
33087
- [class.collapsed]="collapsed"
33088
- [class.expanded]="expanded"
33089
- [class.fullscreen]="fullscreen"
33090
- [class.body-fill]="shell?.bodyLayout === 'fill'"
33091
- [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33092
- [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33093
- [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33094
- [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33095
- [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33096
- [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33097
- [style.--pdx-shell-header-border]="appearance?.header?.borderColor || null"
33098
- [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33099
- [style.--pdx-shell-subtitle-color]="appearance?.header?.subtitleColor || null"
33100
- [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33101
- [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33102
- [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33103
- [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33104
- [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33105
- [style.--pdx-shell-title-weight]="appearance?.typography?.titleWeight || null"
33106
- [style.--pdx-shell-subtitle-size]="appearance?.typography?.subtitleSize || null"
33107
- (click)="stopIfExpanded($event)"
33268
+ <section
33269
+ class="pdx-shell"
33270
+ [class.no-shell]="!shellEnabled"
33271
+ [class.dashboard]="shellEnabled"
33272
+ [class.collapsed]="collapsed"
33273
+ [class.expanded]="expanded"
33274
+ [class.fullscreen]="fullscreen"
33275
+ [class.body-fill]="shell?.bodyLayout === 'fill'"
33276
+ [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33277
+ [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33278
+ [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33279
+ [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33280
+ [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33281
+ [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33282
+ [style.--pdx-shell-header-border]="
33283
+ appearance?.header?.borderColor || null
33284
+ "
33285
+ [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33286
+ [style.--pdx-shell-subtitle-color]="
33287
+ appearance?.header?.subtitleColor || null
33288
+ "
33289
+ [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33290
+ [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33291
+ [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33292
+ [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33293
+ [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33294
+ [style.--pdx-shell-title-weight]="
33295
+ appearance?.typography?.titleWeight || null
33296
+ "
33297
+ [style.--pdx-shell-subtitle-size]="
33298
+ appearance?.typography?.subtitleSize || null
33299
+ "
33300
+ (click)="stopIfExpanded($event)"
33301
+ >
33302
+ @if (showHeader) {
33303
+ <header
33304
+ class="pdx-shell-header"
33305
+ [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33306
+ [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33307
+ [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33308
+ (pointerdown)="onHeaderPointerDown($event)"
33309
+ (keydown)="onHeaderKeydown($event)"
33108
33310
  >
33109
- @if (showHeader) {
33110
- <header
33111
- class="pdx-shell-header"
33112
- [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33113
- [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33114
- [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33115
- (pointerdown)="onHeaderPointerDown($event)"
33116
- (keydown)="onHeaderKeydown($event)"
33117
- >
33118
- <div class="pdx-shell-title">
33119
- @if (shell?.icon) {
33120
- <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33121
- }
33122
- <div class="pdx-shell-text">
33123
- <div class="pdx-shell-title-text">{{ shellText(shell?.title) }}</div>
33124
- @if (shell?.subtitle) {
33125
- <div class="pdx-shell-subtitle">{{ shellText(shell?.subtitle) }}</div>
33126
- }
33311
+ <div class="pdx-shell-title">
33312
+ @if (shell?.icon) {
33313
+ <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33314
+ }
33315
+ <div class="pdx-shell-text">
33316
+ <div class="pdx-shell-title-text">
33317
+ {{ shellText(shell?.title) }}
33127
33318
  </div>
33319
+ @if (shell?.subtitle) {
33320
+ <div class="pdx-shell-subtitle">
33321
+ {{ shellText(shell?.subtitle) }}
33322
+ </div>
33323
+ }
33128
33324
  </div>
33129
- <div class="pdx-shell-actions">
33130
- @if (!expanded && !fullscreen) {
33131
- @for (action of visibleHeaderActions; track action.id) {
33132
- <ng-container>
33133
- @if (action.variant !== 'icon') {
33134
- <button
33135
- [disabled]="action.disabled"
33136
- [matTooltip]="actionText(action.tooltip)"
33137
- matTooltipPosition="above"
33138
- [ngClass]="action.variant === 'outlined' ? 'pdx-action-outlined' : 'pdx-action-text'"
33139
- [class.pdx-shell-action--pressed]="action.pressed === true"
33140
- mat-button
33141
- type="button"
33142
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33143
- (click)="onAction(action, $event)"
33144
- >
33145
- @if (displayActionIcon(action); as actionIcon) {
33146
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33147
- }
33148
- <span class="pdx-action-label">{{ actionText(action.label) }}</span>
33149
- </button>
33150
- }
33151
- @if (action.variant === 'icon') {
33325
+ </div>
33326
+ <div class="pdx-shell-actions">
33327
+ @if (!expanded && !fullscreen) {
33328
+ @for (action of visibleHeaderActions; track action.id) {
33329
+ <ng-container>
33330
+ @if (action.variant !== 'icon') {
33331
+ <button
33332
+ [disabled]="action.disabled"
33333
+ [matTooltip]="actionText(action.tooltip)"
33334
+ matTooltipPosition="above"
33335
+ [ngClass]="
33336
+ action.variant === 'outlined'
33337
+ ? 'pdx-action-outlined'
33338
+ : 'pdx-action-text'
33339
+ "
33340
+ [class.pdx-shell-action--pressed]="
33341
+ action.pressed === true
33342
+ "
33343
+ mat-button
33344
+ type="button"
33345
+ [attr.aria-pressed]="
33346
+ action.pressed == null ? null : action.pressed
33347
+ "
33348
+ (click)="onAction(action, $event)"
33349
+ >
33152
33350
  @if (displayActionIcon(action); as actionIcon) {
33153
- <button
33154
- [praxisIconButton]="actionIcon"
33155
- size="compact"
33156
- [pressed]="actionPressedState(action)"
33157
- [disabled]="action.disabled"
33158
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33159
- matTooltipPosition="above"
33160
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33161
- type="button"
33162
- (click)="onAction(action, $event)"
33163
- ></button>
33351
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33164
33352
  }
33165
- }
33166
- </ng-container>
33167
- }
33168
- @if (overflowHeaderActions.length) {
33169
- <button
33170
- praxisIconButton="ms:more_horiz"
33171
- size="compact"
33172
- type="button"
33173
- [matTooltip]="moreActionsLabel()"
33174
- matTooltipPosition="above"
33175
- [attr.aria-label]="moreActionsLabel()"
33176
- [matMenuTriggerFor]="overflowMenu"
33177
- (click)="$event.stopPropagation()"
33178
- ></button>
33179
- }
33180
- }
33181
- @if (windowActions.length) {
33182
- <div class="pdx-shell-window-actions">
33183
- @for (action of windowActions; track action.id) {
33353
+ <span class="pdx-action-label">{{
33354
+ actionText(action.label)
33355
+ }}</span>
33356
+ </button>
33357
+ }
33358
+ @if (action.variant === 'icon') {
33184
33359
  @if (displayActionIcon(action); as actionIcon) {
33185
33360
  <button
33186
33361
  [praxisIconButton]="actionIcon"
33187
33362
  size="compact"
33188
33363
  [pressed]="actionPressedState(action)"
33189
33364
  [disabled]="action.disabled"
33190
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33365
+ [matTooltip]="
33366
+ actionText(action.tooltip, actionText(action.label))
33367
+ "
33191
33368
  matTooltipPosition="above"
33192
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33369
+ [attr.aria-label]="
33370
+ actionText(
33371
+ action.label,
33372
+ actionText(action.tooltip, action.id)
33373
+ )
33374
+ "
33193
33375
  type="button"
33194
33376
  (click)="onAction(action, $event)"
33195
33377
  ></button>
33196
33378
  }
33197
33379
  }
33198
- </div>
33380
+ </ng-container>
33199
33381
  }
33200
- </div>
33201
- <mat-menu #overflowMenu="matMenu">
33202
- @for (action of overflowHeaderActions; track action.id) {
33382
+ @if (overflowHeaderActions.length) {
33203
33383
  <button
33204
- mat-menu-item
33205
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33206
- (click)="onAction(action, $event)"
33207
- >
33384
+ praxisIconButton="ms:more_horiz"
33385
+ size="compact"
33386
+ type="button"
33387
+ [matTooltip]="moreActionsLabel()"
33388
+ matTooltipPosition="above"
33389
+ [attr.aria-label]="moreActionsLabel()"
33390
+ [matMenuTriggerFor]="overflowMenu"
33391
+ (click)="$event.stopPropagation()"
33392
+ ></button>
33393
+ }
33394
+ }
33395
+ @if (windowActions.length) {
33396
+ <div class="pdx-shell-window-actions">
33397
+ @for (action of windowActions; track action.id) {
33208
33398
  @if (displayActionIcon(action); as actionIcon) {
33209
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33399
+ <button
33400
+ [praxisIconButton]="actionIcon"
33401
+ size="compact"
33402
+ [pressed]="actionPressedState(action)"
33403
+ [disabled]="action.disabled"
33404
+ [matTooltip]="
33405
+ actionText(action.tooltip, actionText(action.label))
33406
+ "
33407
+ matTooltipPosition="above"
33408
+ [attr.aria-label]="
33409
+ actionText(
33410
+ action.label,
33411
+ actionText(action.tooltip, action.id)
33412
+ )
33413
+ "
33414
+ type="button"
33415
+ (click)="onAction(action, $event)"
33416
+ ></button>
33210
33417
  }
33211
- <span>{{ actionText(action.label, action.id) }}</span>
33212
- </button>
33213
- }
33214
- </mat-menu>
33215
- </header>
33216
- }
33217
- <div class="pdx-shell-body" [class.hidden]="collapsed">
33218
- <ng-content></ng-content>
33219
- </div>
33220
- </section>
33221
- @if (expanded || fullscreen) {
33222
- <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33418
+ }
33419
+ </div>
33420
+ }
33421
+ </div>
33422
+ <mat-menu #overflowMenu="matMenu">
33423
+ @for (action of overflowHeaderActions; track action.id) {
33424
+ <button
33425
+ mat-menu-item
33426
+ [attr.aria-pressed]="
33427
+ action.pressed == null ? null : action.pressed
33428
+ "
33429
+ (click)="onAction(action, $event)"
33430
+ >
33431
+ @if (displayActionIcon(action); as actionIcon) {
33432
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33433
+ }
33434
+ <span>{{ actionText(action.label, action.id) }}</span>
33435
+ </button>
33436
+ }
33437
+ </mat-menu>
33438
+ </header>
33223
33439
  }
33224
- `, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33440
+ <div class="pdx-shell-body" [class.hidden]="collapsed">
33441
+ <ng-content></ng-content>
33442
+ </div>
33443
+ </section>
33444
+ @if (expanded || fullscreen) {
33445
+ <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33446
+ }
33447
+ `, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var( --pdx-shell-card-bg, var( --pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low) ) );border:1px solid var( --pdx-shell-card-border, var( --pdx-dashboard-card-border, var(--md-sys-color-outline-variant) ) );border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var( --pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06) );overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var( --pdx-shell-header-bg, var(--md-sys-color-surface-container) )}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);color:var( --pdx-shell-subtitle-color, var(--md-sys-color-on-surface-variant, currentColor) );white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
33225
33448
  }
33226
33449
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellComponent, decorators: [{
33227
33450
  type: Component,
33228
- args: [{ selector: 'praxis-widget-shell', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatMenuModule, MatTooltipModule, PraxisIconButtonComponent, PraxisIconDirective], providers: [providePraxisI18nConfig(WIDGET_SHELL_I18N_CONFIG)], template: `
33229
- <section
33230
- class="pdx-shell"
33231
- [class.no-shell]="!shellEnabled"
33232
- [class.dashboard]="shellEnabled"
33233
- [class.collapsed]="collapsed"
33234
- [class.expanded]="expanded"
33235
- [class.fullscreen]="fullscreen"
33236
- [class.body-fill]="shell?.bodyLayout === 'fill'"
33237
- [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33238
- [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33239
- [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33240
- [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33241
- [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33242
- [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33243
- [style.--pdx-shell-header-border]="appearance?.header?.borderColor || null"
33244
- [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33245
- [style.--pdx-shell-subtitle-color]="appearance?.header?.subtitleColor || null"
33246
- [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33247
- [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33248
- [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33249
- [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33250
- [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33251
- [style.--pdx-shell-title-weight]="appearance?.typography?.titleWeight || null"
33252
- [style.--pdx-shell-subtitle-size]="appearance?.typography?.subtitleSize || null"
33253
- (click)="stopIfExpanded($event)"
33451
+ args: [{ selector: 'praxis-widget-shell', standalone: true, imports: [
33452
+ CommonModule,
33453
+ MatButtonModule,
33454
+ MatIconModule,
33455
+ MatMenuModule,
33456
+ MatTooltipModule,
33457
+ PraxisIconButtonComponent,
33458
+ PraxisIconDirective,
33459
+ ], providers: [providePraxisI18nConfig(WIDGET_SHELL_I18N_CONFIG)], template: `
33460
+ <section
33461
+ class="pdx-shell"
33462
+ [class.no-shell]="!shellEnabled"
33463
+ [class.dashboard]="shellEnabled"
33464
+ [class.collapsed]="collapsed"
33465
+ [class.expanded]="expanded"
33466
+ [class.fullscreen]="fullscreen"
33467
+ [class.body-fill]="shell?.bodyLayout === 'fill'"
33468
+ [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33469
+ [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33470
+ [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33471
+ [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33472
+ [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33473
+ [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33474
+ [style.--pdx-shell-header-border]="
33475
+ appearance?.header?.borderColor || null
33476
+ "
33477
+ [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33478
+ [style.--pdx-shell-subtitle-color]="
33479
+ appearance?.header?.subtitleColor || null
33480
+ "
33481
+ [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33482
+ [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33483
+ [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33484
+ [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33485
+ [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33486
+ [style.--pdx-shell-title-weight]="
33487
+ appearance?.typography?.titleWeight || null
33488
+ "
33489
+ [style.--pdx-shell-subtitle-size]="
33490
+ appearance?.typography?.subtitleSize || null
33491
+ "
33492
+ (click)="stopIfExpanded($event)"
33493
+ >
33494
+ @if (showHeader) {
33495
+ <header
33496
+ class="pdx-shell-header"
33497
+ [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33498
+ [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33499
+ [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33500
+ (pointerdown)="onHeaderPointerDown($event)"
33501
+ (keydown)="onHeaderKeydown($event)"
33254
33502
  >
33255
- @if (showHeader) {
33256
- <header
33257
- class="pdx-shell-header"
33258
- [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33259
- [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33260
- [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33261
- (pointerdown)="onHeaderPointerDown($event)"
33262
- (keydown)="onHeaderKeydown($event)"
33263
- >
33264
- <div class="pdx-shell-title">
33265
- @if (shell?.icon) {
33266
- <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33267
- }
33268
- <div class="pdx-shell-text">
33269
- <div class="pdx-shell-title-text">{{ shellText(shell?.title) }}</div>
33270
- @if (shell?.subtitle) {
33271
- <div class="pdx-shell-subtitle">{{ shellText(shell?.subtitle) }}</div>
33272
- }
33503
+ <div class="pdx-shell-title">
33504
+ @if (shell?.icon) {
33505
+ <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33506
+ }
33507
+ <div class="pdx-shell-text">
33508
+ <div class="pdx-shell-title-text">
33509
+ {{ shellText(shell?.title) }}
33273
33510
  </div>
33511
+ @if (shell?.subtitle) {
33512
+ <div class="pdx-shell-subtitle">
33513
+ {{ shellText(shell?.subtitle) }}
33514
+ </div>
33515
+ }
33274
33516
  </div>
33275
- <div class="pdx-shell-actions">
33276
- @if (!expanded && !fullscreen) {
33277
- @for (action of visibleHeaderActions; track action.id) {
33278
- <ng-container>
33279
- @if (action.variant !== 'icon') {
33280
- <button
33281
- [disabled]="action.disabled"
33282
- [matTooltip]="actionText(action.tooltip)"
33283
- matTooltipPosition="above"
33284
- [ngClass]="action.variant === 'outlined' ? 'pdx-action-outlined' : 'pdx-action-text'"
33285
- [class.pdx-shell-action--pressed]="action.pressed === true"
33286
- mat-button
33287
- type="button"
33288
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33289
- (click)="onAction(action, $event)"
33290
- >
33291
- @if (displayActionIcon(action); as actionIcon) {
33292
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33293
- }
33294
- <span class="pdx-action-label">{{ actionText(action.label) }}</span>
33295
- </button>
33296
- }
33297
- @if (action.variant === 'icon') {
33517
+ </div>
33518
+ <div class="pdx-shell-actions">
33519
+ @if (!expanded && !fullscreen) {
33520
+ @for (action of visibleHeaderActions; track action.id) {
33521
+ <ng-container>
33522
+ @if (action.variant !== 'icon') {
33523
+ <button
33524
+ [disabled]="action.disabled"
33525
+ [matTooltip]="actionText(action.tooltip)"
33526
+ matTooltipPosition="above"
33527
+ [ngClass]="
33528
+ action.variant === 'outlined'
33529
+ ? 'pdx-action-outlined'
33530
+ : 'pdx-action-text'
33531
+ "
33532
+ [class.pdx-shell-action--pressed]="
33533
+ action.pressed === true
33534
+ "
33535
+ mat-button
33536
+ type="button"
33537
+ [attr.aria-pressed]="
33538
+ action.pressed == null ? null : action.pressed
33539
+ "
33540
+ (click)="onAction(action, $event)"
33541
+ >
33298
33542
  @if (displayActionIcon(action); as actionIcon) {
33299
- <button
33300
- [praxisIconButton]="actionIcon"
33301
- size="compact"
33302
- [pressed]="actionPressedState(action)"
33303
- [disabled]="action.disabled"
33304
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33305
- matTooltipPosition="above"
33306
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33307
- type="button"
33308
- (click)="onAction(action, $event)"
33309
- ></button>
33543
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33310
33544
  }
33311
- }
33312
- </ng-container>
33313
- }
33314
- @if (overflowHeaderActions.length) {
33315
- <button
33316
- praxisIconButton="ms:more_horiz"
33317
- size="compact"
33318
- type="button"
33319
- [matTooltip]="moreActionsLabel()"
33320
- matTooltipPosition="above"
33321
- [attr.aria-label]="moreActionsLabel()"
33322
- [matMenuTriggerFor]="overflowMenu"
33323
- (click)="$event.stopPropagation()"
33324
- ></button>
33325
- }
33326
- }
33327
- @if (windowActions.length) {
33328
- <div class="pdx-shell-window-actions">
33329
- @for (action of windowActions; track action.id) {
33545
+ <span class="pdx-action-label">{{
33546
+ actionText(action.label)
33547
+ }}</span>
33548
+ </button>
33549
+ }
33550
+ @if (action.variant === 'icon') {
33330
33551
  @if (displayActionIcon(action); as actionIcon) {
33331
33552
  <button
33332
33553
  [praxisIconButton]="actionIcon"
33333
33554
  size="compact"
33334
33555
  [pressed]="actionPressedState(action)"
33335
33556
  [disabled]="action.disabled"
33336
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33557
+ [matTooltip]="
33558
+ actionText(action.tooltip, actionText(action.label))
33559
+ "
33337
33560
  matTooltipPosition="above"
33338
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33561
+ [attr.aria-label]="
33562
+ actionText(
33563
+ action.label,
33564
+ actionText(action.tooltip, action.id)
33565
+ )
33566
+ "
33339
33567
  type="button"
33340
33568
  (click)="onAction(action, $event)"
33341
33569
  ></button>
33342
33570
  }
33343
33571
  }
33344
- </div>
33572
+ </ng-container>
33345
33573
  }
33346
- </div>
33347
- <mat-menu #overflowMenu="matMenu">
33348
- @for (action of overflowHeaderActions; track action.id) {
33574
+ @if (overflowHeaderActions.length) {
33349
33575
  <button
33350
- mat-menu-item
33351
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33352
- (click)="onAction(action, $event)"
33353
- >
33576
+ praxisIconButton="ms:more_horiz"
33577
+ size="compact"
33578
+ type="button"
33579
+ [matTooltip]="moreActionsLabel()"
33580
+ matTooltipPosition="above"
33581
+ [attr.aria-label]="moreActionsLabel()"
33582
+ [matMenuTriggerFor]="overflowMenu"
33583
+ (click)="$event.stopPropagation()"
33584
+ ></button>
33585
+ }
33586
+ }
33587
+ @if (windowActions.length) {
33588
+ <div class="pdx-shell-window-actions">
33589
+ @for (action of windowActions; track action.id) {
33354
33590
  @if (displayActionIcon(action); as actionIcon) {
33355
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33591
+ <button
33592
+ [praxisIconButton]="actionIcon"
33593
+ size="compact"
33594
+ [pressed]="actionPressedState(action)"
33595
+ [disabled]="action.disabled"
33596
+ [matTooltip]="
33597
+ actionText(action.tooltip, actionText(action.label))
33598
+ "
33599
+ matTooltipPosition="above"
33600
+ [attr.aria-label]="
33601
+ actionText(
33602
+ action.label,
33603
+ actionText(action.tooltip, action.id)
33604
+ )
33605
+ "
33606
+ type="button"
33607
+ (click)="onAction(action, $event)"
33608
+ ></button>
33356
33609
  }
33357
- <span>{{ actionText(action.label, action.id) }}</span>
33358
- </button>
33359
- }
33360
- </mat-menu>
33361
- </header>
33362
- }
33363
- <div class="pdx-shell-body" [class.hidden]="collapsed">
33364
- <ng-content></ng-content>
33365
- </div>
33366
- </section>
33367
- @if (expanded || fullscreen) {
33368
- <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33610
+ }
33611
+ </div>
33612
+ }
33613
+ </div>
33614
+ <mat-menu #overflowMenu="matMenu">
33615
+ @for (action of overflowHeaderActions; track action.id) {
33616
+ <button
33617
+ mat-menu-item
33618
+ [attr.aria-pressed]="
33619
+ action.pressed == null ? null : action.pressed
33620
+ "
33621
+ (click)="onAction(action, $event)"
33622
+ >
33623
+ @if (displayActionIcon(action); as actionIcon) {
33624
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33625
+ }
33626
+ <span>{{ actionText(action.label, action.id) }}</span>
33627
+ </button>
33628
+ }
33629
+ </mat-menu>
33630
+ </header>
33369
33631
  }
33370
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
33632
+ <div class="pdx-shell-body" [class.hidden]="collapsed">
33633
+ <ng-content></ng-content>
33634
+ </div>
33635
+ </section>
33636
+ @if (expanded || fullscreen) {
33637
+ <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33638
+ }
33639
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var( --pdx-shell-card-bg, var( --pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low) ) );border:1px solid var( --pdx-shell-card-border, var( --pdx-dashboard-card-border, var(--md-sys-color-outline-variant) ) );border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var( --pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06) );overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var( --pdx-shell-header-bg, var(--md-sys-color-surface-container) )}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);color:var( --pdx-shell-subtitle-color, var(--md-sys-color-on-surface-variant, currentColor) );white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
33371
33640
  }], propDecorators: { hostCollapsed: [{
33372
33641
  type: HostBinding,
33373
33642
  args: ['class.pdx-widget-shell-collapsed']
@@ -33734,6 +34003,149 @@ const BUILTIN_PAGE_THEME_PRESETS = {
33734
34003
  },
33735
34004
  };
33736
34005
 
34006
+ class WidgetPageCompositionFactory {
34007
+ create(page) {
34008
+ const normalizedState = this.normalizeState(page.state);
34009
+ const widgetsByKey = this.indexWidgets(page.widgets);
34010
+ return {
34011
+ widgetOrder: page.widgets.map((widget) => widget.key),
34012
+ widgetsByKey,
34013
+ links: this.readCanonicalLinks(page),
34014
+ state: {
34015
+ primaryValues: this.materializePrimaryValues(normalizedState),
34016
+ schema: this.clone(normalizedState.schema) || {},
34017
+ derivedDefinitions: this.clone(normalizedState.derived) || {},
34018
+ },
34019
+ context: this.clone(page.context) || {},
34020
+ };
34021
+ }
34022
+ readCanonicalLinks(page) {
34023
+ const links = this.clone(page.composition?.links) || [];
34024
+ this.assertCanonicalLinks(links);
34025
+ return links;
34026
+ }
34027
+ assertCanonicalLinks(links) {
34028
+ for (const link of links) {
34029
+ const rawLink = link;
34030
+ const id = String(rawLink['id'] ?? 'unknown-link');
34031
+ const condition = rawLink['condition'];
34032
+ const conditions = rawLink['conditions'];
34033
+ const meta = rawLink['meta'];
34034
+ const policy = rawLink['policy'];
34035
+ if (typeof condition === 'string') {
34036
+ throw new Error(`WidgetPageCompositionFactory no longer accepts string condition in composition.links for '${id}'. Use canonical Json Logic in condition.`);
34037
+ }
34038
+ if (conditions !== undefined) {
34039
+ throw new Error(`WidgetPageCompositionFactory no longer accepts legacy conditions[] in composition.links for '${id}'. Use canonical Json Logic in condition.`);
34040
+ }
34041
+ if (meta && typeof meta === 'object' && !Array.isArray(meta) && 'filterExpr' in meta) {
34042
+ throw new Error(`WidgetPageCompositionFactory no longer accepts meta.filterExpr in composition.links for '${id}'. Use canonical Json Logic in condition.`);
34043
+ }
34044
+ if (condition !== undefined
34045
+ && condition !== null
34046
+ && (typeof condition !== 'object' || Array.isArray(condition))) {
34047
+ throw new Error(`WidgetPageCompositionFactory requires composition.links[].condition to be canonical Json Logic or null for '${id}'.`);
34048
+ }
34049
+ if (condition && !this.isJsonLogicLike(condition)) {
34050
+ throw new Error(`WidgetPageCompositionFactory requires composition.links[].condition to be a canonical Json Logic expression for '${id}'.`);
34051
+ }
34052
+ if (policy && typeof policy === 'object' && !Array.isArray(policy)) {
34053
+ const rawPolicy = policy;
34054
+ const delivery = rawPolicy['delivery'];
34055
+ const errorPolicy = rawPolicy['errorPolicy'];
34056
+ if (delivery !== undefined && delivery !== 'sync') {
34057
+ throw new Error(`WidgetPageCompositionFactory no longer accepts non-executable delivery '${String(delivery)}' for '${id}'. Composition dispatch is synchronously ordered; use delivery 'sync' or omit it.`);
34058
+ }
34059
+ if (errorPolicy !== undefined
34060
+ && errorPolicy !== 'diagnostic'
34061
+ && errorPolicy !== 'drop'
34062
+ && errorPolicy !== 'halt-page') {
34063
+ throw new Error(`WidgetPageCompositionFactory requires a supported errorPolicy for '${id}': diagnostic, drop, or halt-page.`);
34064
+ }
34065
+ }
34066
+ }
34067
+ }
34068
+ isJsonLogicLike(condition) {
34069
+ return Object.keys(condition).length > 0;
34070
+ }
34071
+ indexWidgets(widgets) {
34072
+ const widgetsByKey = {};
34073
+ for (const widget of widgets) {
34074
+ const key = (widget.key || '').trim();
34075
+ if (!key) {
34076
+ throw new Error('WidgetPageCompositionFactory requires every widget to have a non-empty key.');
34077
+ }
34078
+ if (widgetsByKey[key]) {
34079
+ throw new Error(`WidgetPageCompositionFactory cannot normalize duplicate widget key '${key}'.`);
34080
+ }
34081
+ widgetsByKey[key] = this.clone(widget);
34082
+ }
34083
+ return widgetsByKey;
34084
+ }
34085
+ normalizeState(state) {
34086
+ if (!state) {
34087
+ return { values: {} };
34088
+ }
34089
+ const isStructured = typeof state === 'object'
34090
+ && !Array.isArray(state)
34091
+ && ('values' in state || 'schema' in state || 'derived' in state);
34092
+ if (isStructured) {
34093
+ const structured = state;
34094
+ return {
34095
+ values: this.clone(structured.values) || {},
34096
+ schema: this.clone(structured.schema),
34097
+ derived: this.clone(structured.derived),
34098
+ };
34099
+ }
34100
+ return { values: this.clone(state) || {} };
34101
+ }
34102
+ materializePrimaryValues(state) {
34103
+ const values = this.clone(state.values) || {};
34104
+ for (const [path, schema] of Object.entries(state.schema || {})) {
34105
+ if (schema?.initial === undefined) {
34106
+ continue;
34107
+ }
34108
+ if (this.readPath(values, path) !== undefined) {
34109
+ continue;
34110
+ }
34111
+ this.writePath(values, path, this.clone(schema.initial));
34112
+ }
34113
+ return values;
34114
+ }
34115
+ readPath(source, path) {
34116
+ return path
34117
+ .split('.')
34118
+ .filter(Boolean)
34119
+ .reduce((current, segment) => {
34120
+ if (current == null || typeof current !== 'object') {
34121
+ return undefined;
34122
+ }
34123
+ return current[segment];
34124
+ }, source);
34125
+ }
34126
+ writePath(target, path, value) {
34127
+ const segments = path.split('.').filter(Boolean);
34128
+ if (!segments.length) {
34129
+ return;
34130
+ }
34131
+ let cursor = target;
34132
+ for (const segment of segments.slice(0, -1)) {
34133
+ const current = cursor[segment];
34134
+ if (current == null || typeof current !== 'object' || Array.isArray(current)) {
34135
+ cursor[segment] = {};
34136
+ }
34137
+ cursor = cursor[segment];
34138
+ }
34139
+ cursor[segments[segments.length - 1]] = value;
34140
+ }
34141
+ clone(value) {
34142
+ if (value == null || typeof value !== 'object') {
34143
+ return value;
34144
+ }
34145
+ return JSON.parse(JSON.stringify(value));
34146
+ }
34147
+ }
34148
+
33737
34149
  class ConnectionManagerService {
33738
34150
  /** Extract value from an object using dot-path (e.g., 'payload.row.id'). */
33739
34151
  extractByPath(obj, path) {
@@ -34602,10 +35014,30 @@ class NestedPortCatalogService {
34602
35014
  return { ports, diagnostics };
34603
35015
  }
34604
35016
  resolveEndpoint(page, registry, options) {
34605
- return this.resolve(page, registry).ports.find((port) => port.ownerWidgetKey === options.ownerWidgetKey
34606
- && port.port.id === options.portId
34607
- && port.port.direction === options.direction
34608
- && this.isSamePath(port.nestedPath, options.nestedPath));
35017
+ return this.resolveEndpointWithDiagnostics(page, registry, options).port;
35018
+ }
35019
+ resolveEndpointWithDiagnostics(page, registry, options) {
35020
+ const port = this.resolve(page, registry).ports.find((candidate) => candidate.ownerWidgetKey === options.ownerWidgetKey
35021
+ && candidate.port.id === options.portId
35022
+ && candidate.port.direction === options.direction
35023
+ && nestedPortPathIdentity(candidate.nestedPath) === nestedPortPathIdentity(options.nestedPath));
35024
+ const terminal = options.nestedPath[options.nestedPath.length - 1];
35025
+ const componentTypeHint = options.componentType
35026
+ ?? (terminal?.kind === 'widget' ? terminal.componentType : undefined);
35027
+ if (!port || !componentTypeHint || componentTypeHint === port.componentId) {
35028
+ return { port, diagnostics: [] };
35029
+ }
35030
+ return {
35031
+ port,
35032
+ diagnostics: [{
35033
+ code: 'NESTED_WIDGET_COMPONENT_TYPE_MISMATCH',
35034
+ severity: 'error',
35035
+ ownerWidgetKey: options.ownerWidgetKey,
35036
+ nestedPath: this.clone(options.nestedPath),
35037
+ componentId: port.componentId,
35038
+ message: `Nested endpoint componentType '${componentTypeHint}' conflicts with materialized child '${port.componentId}'.`,
35039
+ }],
35040
+ };
34609
35041
  }
34610
35042
  hasStableTerminalKey(nestedPath) {
34611
35043
  const terminal = nestedPath[nestedPath.length - 1];
@@ -34616,9 +35048,6 @@ class NestedPortCatalogService {
34616
35048
  containerPath(nestedPath) {
34617
35049
  return nestedPath.slice(0, -1).map((segment) => this.clone(segment));
34618
35050
  }
34619
- isSamePath(left, right) {
34620
- return JSON.stringify(left) === JSON.stringify(right);
34621
- }
34622
35051
  clone(value) {
34623
35052
  if (value == null || typeof value !== 'object') {
34624
35053
  return value;
@@ -34626,6 +35055,17 @@ class NestedPortCatalogService {
34626
35055
  return JSON.parse(JSON.stringify(value));
34627
35056
  }
34628
35057
  }
35058
+ /** Stable nested identity excludes componentType, which is only a consistency hint. */
35059
+ function nestedPortPathIdentity(path) {
35060
+ return JSON.stringify(path.map((segment) => ({
35061
+ kind: segment.kind,
35062
+ ...(segment.id ? { id: segment.id } : {}),
35063
+ ...(segment.key ? { key: segment.key } : {}),
35064
+ ...(!segment.id && !segment.key && segment.index !== undefined
35065
+ ? { index: segment.index }
35066
+ : {}),
35067
+ })));
35068
+ }
34629
35069
 
34630
35070
  const COMPOSITION_RULE_ROOTS$1 = ['source', 'event', 'payload', 'state', 'context', 'meta'];
34631
35071
  const COMPATIBLE_TARGET_KINDS = {
@@ -34918,11 +35358,12 @@ class CompositionValidatorService {
34918
35358
  }));
34919
35359
  continue;
34920
35360
  }
34921
- if (endpoint.ref.componentType && endpoint.ref.componentType !== resolved.componentId) {
35361
+ const componentTypeHint = endpoint.ref.componentType ?? terminal.componentType;
35362
+ if (componentTypeHint && componentTypeHint !== resolved.componentId) {
34922
35363
  diagnostics.push(this.createDiagnostic(link, 'SEMANTIC_NESTED_COMPONENT_TYPE_MISMATCH', 'error', `O componentType do endpoint nested do link ${link.id} nao corresponde ao componente filho resolvido.`, this.nestedEndpointSubject(link, endpoint, nestedPath), {
34923
35364
  ownerWidgetKey: endpoint.ref.widget,
34924
35365
  nestedPath,
34925
- expectedComponentType: endpoint.ref.componentType,
35366
+ expectedComponentType: componentTypeHint,
34926
35367
  actualComponentType: resolved.componentId,
34927
35368
  }));
34928
35369
  }
@@ -35214,7 +35655,8 @@ class CompositionValidatorService {
35214
35655
  };
35215
35656
  }
35216
35657
  isSameNestedPath(left, right) {
35217
- return JSON.stringify(left) === JSON.stringify(right);
35658
+ return nestedPortPathIdentity(left)
35659
+ === nestedPortPathIdentity(right);
35218
35660
  }
35219
35661
  }
35220
35662
 
@@ -37925,149 +38367,6 @@ const DYNAMIC_WIDGET_PAGE_I18N_CONFIG = {
37925
38367
  },
37926
38368
  };
37927
38369
 
37928
- class WidgetPageCompositionFactory {
37929
- create(page) {
37930
- const normalizedState = this.normalizeState(page.state);
37931
- const widgetsByKey = this.indexWidgets(page.widgets);
37932
- return {
37933
- widgetOrder: page.widgets.map((widget) => widget.key),
37934
- widgetsByKey,
37935
- links: this.readCanonicalLinks(page),
37936
- state: {
37937
- primaryValues: this.materializePrimaryValues(normalizedState),
37938
- schema: this.clone(normalizedState.schema) || {},
37939
- derivedDefinitions: this.clone(normalizedState.derived) || {},
37940
- },
37941
- context: this.clone(page.context) || {},
37942
- };
37943
- }
37944
- readCanonicalLinks(page) {
37945
- const links = this.clone(page.composition?.links) || [];
37946
- this.assertCanonicalLinks(links);
37947
- return links;
37948
- }
37949
- assertCanonicalLinks(links) {
37950
- for (const link of links) {
37951
- const rawLink = link;
37952
- const id = String(rawLink['id'] ?? 'unknown-link');
37953
- const condition = rawLink['condition'];
37954
- const conditions = rawLink['conditions'];
37955
- const meta = rawLink['meta'];
37956
- const policy = rawLink['policy'];
37957
- if (typeof condition === 'string') {
37958
- throw new Error(`WidgetPageCompositionFactory no longer accepts string condition in composition.links for '${id}'. Use canonical Json Logic in condition.`);
37959
- }
37960
- if (conditions !== undefined) {
37961
- throw new Error(`WidgetPageCompositionFactory no longer accepts legacy conditions[] in composition.links for '${id}'. Use canonical Json Logic in condition.`);
37962
- }
37963
- if (meta && typeof meta === 'object' && !Array.isArray(meta) && 'filterExpr' in meta) {
37964
- throw new Error(`WidgetPageCompositionFactory no longer accepts meta.filterExpr in composition.links for '${id}'. Use canonical Json Logic in condition.`);
37965
- }
37966
- if (condition !== undefined
37967
- && condition !== null
37968
- && (typeof condition !== 'object' || Array.isArray(condition))) {
37969
- throw new Error(`WidgetPageCompositionFactory requires composition.links[].condition to be canonical Json Logic or null for '${id}'.`);
37970
- }
37971
- if (condition && !this.isJsonLogicLike(condition)) {
37972
- throw new Error(`WidgetPageCompositionFactory requires composition.links[].condition to be a canonical Json Logic expression for '${id}'.`);
37973
- }
37974
- if (policy && typeof policy === 'object' && !Array.isArray(policy)) {
37975
- const rawPolicy = policy;
37976
- const delivery = rawPolicy['delivery'];
37977
- const errorPolicy = rawPolicy['errorPolicy'];
37978
- if (delivery !== undefined && delivery !== 'sync') {
37979
- throw new Error(`WidgetPageCompositionFactory no longer accepts non-executable delivery '${String(delivery)}' for '${id}'. Composition dispatch is synchronously ordered; use delivery 'sync' or omit it.`);
37980
- }
37981
- if (errorPolicy !== undefined
37982
- && errorPolicy !== 'diagnostic'
37983
- && errorPolicy !== 'drop'
37984
- && errorPolicy !== 'halt-page') {
37985
- throw new Error(`WidgetPageCompositionFactory requires a supported errorPolicy for '${id}': diagnostic, drop, or halt-page.`);
37986
- }
37987
- }
37988
- }
37989
- }
37990
- isJsonLogicLike(condition) {
37991
- return Object.keys(condition).length > 0;
37992
- }
37993
- indexWidgets(widgets) {
37994
- const widgetsByKey = {};
37995
- for (const widget of widgets) {
37996
- const key = (widget.key || '').trim();
37997
- if (!key) {
37998
- throw new Error('WidgetPageCompositionFactory requires every widget to have a non-empty key.');
37999
- }
38000
- if (widgetsByKey[key]) {
38001
- throw new Error(`WidgetPageCompositionFactory cannot normalize duplicate widget key '${key}'.`);
38002
- }
38003
- widgetsByKey[key] = this.clone(widget);
38004
- }
38005
- return widgetsByKey;
38006
- }
38007
- normalizeState(state) {
38008
- if (!state) {
38009
- return { values: {} };
38010
- }
38011
- const isStructured = typeof state === 'object'
38012
- && !Array.isArray(state)
38013
- && ('values' in state || 'schema' in state || 'derived' in state);
38014
- if (isStructured) {
38015
- const structured = state;
38016
- return {
38017
- values: this.clone(structured.values) || {},
38018
- schema: this.clone(structured.schema),
38019
- derived: this.clone(structured.derived),
38020
- };
38021
- }
38022
- return { values: this.clone(state) || {} };
38023
- }
38024
- materializePrimaryValues(state) {
38025
- const values = this.clone(state.values) || {};
38026
- for (const [path, schema] of Object.entries(state.schema || {})) {
38027
- if (schema?.initial === undefined) {
38028
- continue;
38029
- }
38030
- if (this.readPath(values, path) !== undefined) {
38031
- continue;
38032
- }
38033
- this.writePath(values, path, this.clone(schema.initial));
38034
- }
38035
- return values;
38036
- }
38037
- readPath(source, path) {
38038
- return path
38039
- .split('.')
38040
- .filter(Boolean)
38041
- .reduce((current, segment) => {
38042
- if (current == null || typeof current !== 'object') {
38043
- return undefined;
38044
- }
38045
- return current[segment];
38046
- }, source);
38047
- }
38048
- writePath(target, path, value) {
38049
- const segments = path.split('.').filter(Boolean);
38050
- if (!segments.length) {
38051
- return;
38052
- }
38053
- let cursor = target;
38054
- for (const segment of segments.slice(0, -1)) {
38055
- const current = cursor[segment];
38056
- if (current == null || typeof current !== 'object' || Array.isArray(current)) {
38057
- cursor[segment] = {};
38058
- }
38059
- cursor = cursor[segment];
38060
- }
38061
- cursor[segments[segments.length - 1]] = value;
38062
- }
38063
- clone(value) {
38064
- if (value == null || typeof value !== 'object') {
38065
- return value;
38066
- }
38067
- return JSON.parse(JSON.stringify(value));
38068
- }
38069
- }
38070
-
38071
38370
  const CANVAS_RESIZE_HANDLES = [
38072
38371
  { id: 'north', className: 'pdx-canvas-resize--north' },
38073
38372
  { id: 'south', className: 'pdx-canvas-resize--south' },
@@ -39475,9 +39774,7 @@ class DynamicWidgetPageComponent {
39475
39774
  return this.isAuthoringCapabilityEnabled('canvas');
39476
39775
  }
39477
39776
  canOpenPageSettings() {
39478
- return this.isAuthoringCapabilityEnabled('pageSettings')
39479
- && this.showPageSettingsButton
39480
- && !!(this.pageEditorComponent || this.defaultPageEditor);
39777
+ return this.showPageSettingsButton && this.canInvokePageSettings();
39481
39778
  }
39482
39779
  canOpenWidgetShellSettings() {
39483
39780
  return this.isWidgetShellCapabilityEnabled()
@@ -40211,7 +40508,7 @@ class DynamicWidgetPageComponent {
40211
40508
  return (endpoint.kind === 'component-port' && endpoint.ref.widget === widgetKey);
40212
40509
  }
40213
40510
  openPageSettings() {
40214
- if (!this.canOpenPageSettings())
40511
+ if (!this.canInvokePageSettings())
40215
40512
  return;
40216
40513
  if (!this.settingsPanel)
40217
40514
  return;
@@ -40237,6 +40534,10 @@ class DynamicWidgetPageComponent {
40237
40534
  ref.applied$.subscribe((result) => this.applyPageLayout(result, false));
40238
40535
  ref.saved$.subscribe((result) => this.applyPageLayout(result, true));
40239
40536
  }
40537
+ canInvokePageSettings() {
40538
+ return this.isAuthoringCapabilityEnabled('pageSettings')
40539
+ && !!(this.pageEditorComponent || this.defaultPageEditor);
40540
+ }
40240
40541
  applyWidgetShell(key, result, persist) {
40241
40542
  if (!result)
40242
40543
  return;
@@ -46384,4 +46685,4 @@ function provideHookWhitelist(allowed) {
46384
46685
  * Generated bundle index. Do not edit.
46385
46686
  */
46386
46687
 
46387
- export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, COMPONENT_METADATA_REGISTRY_I18N_CONFIG, COMPONENT_METADATA_REGISTRY_I18N_NAMESPACE, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentAuthoringManifestProjectionError, ComponentKeyService, ComponentMetadataRegistry, ComponentRuntimeProfileService, CompositionRuntimeFacade, CompositionValidatorService, ConsoleLoggerSink, CrudOperationResolutionService, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_JSON_LOGIC_OPERATORS, DEFAULT_TABLE_CONFIG, DOMAIN_CATALOG_COMPONENT_CONTEXT_PACK, DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DomainCatalogService, DomainKnowledgeService, DomainRuleService, DynamicFormService, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, EnterpriseRuntimeContextService, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NestedPortCatalogService, NestedWidgetConfigAccessor, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_ACTION_CONTROL_DEFAULTS, PRAXIS_ACTION_CONTROL_VARS, PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, PRAXIS_COLLECTION_EXPORT_PROVIDER, PRAXIS_COLLECTION_SEARCH_DEFAULTS, PRAXIS_COLLECTION_SEARCH_VARS, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS, PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY, PRAXIS_EXPORT_FORMULA_PREFIXES, PRAXIS_EXPORT_SECURITY_POLICY, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_JSON_LOGIC_OPERATORS, PRAXIS_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_QUERY_FILTER_EXPRESSION_SCHEMA_VERSION, PRAXIS_RELATED_RESOURCE_OUTLET_AUTHORING_MANIFEST, PRAXIS_RELATED_RESOURCE_OUTLET_COMPONENT_METADATA, PRAXIS_RELATED_RESOURCE_OUTLET_PORTS, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TABLE_DETAIL_INLINE_NODE_RESOLVERS, PRAXIS_TABLE_DETAIL_INLINE_RENDERERS, PRAXIS_TABLE_DETAIL_RESOURCE_RESOLVER, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_THEME_SURFACE_DEFAULTS, PRAXIS_THEME_SURFACE_VARS, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCollectionExportService, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisHttpCollectionExportProvider, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, PraxisIconPickerComponent, PraxisJsonLogicError, PraxisJsonLogicService, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRelatedResourceOutletComponent, PraxisRelatedResourceOutletConfigEditorComponent, PraxisResourceIdentityComponent, PraxisRichTextBlockComponent, PraxisRuntimeComponentObservationRegistryService, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RelatedResourceSurfaceResolverService, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceRecordOpenError, ResourceRecordOpenService, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, SURFACE_DRAWER_CONTENT_DATA, SURFACE_DRAWER_REF, SURFACE_NAVIGATION_I18N_CONFIG, SURFACE_NAVIGATION_I18N_NAMESPACE, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceNavigationError, SurfaceOpenActionEditorComponent, SurfaceOpenMaterializerService, SurfaceOutletRegistryService, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, assertPraxisCollectionExportArtifact, assertPraxisRuntimeComponentObservationSerializable, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildPraxisActionControlCss, buildPraxisCollectionSearchCss, buildPraxisEffectDistinctKey, buildPraxisLayerScaleCss, buildPraxisThemeSurfaceCss, buildSchemaId, buildSchemaIdStorageKeySegment, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, classifyEntityLookupResult, clonePraxisRuntimeComponentObservation, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createEmptyRichContentDocument, createFieldLayoutItem, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, domainKnowledgeTimelineToRichContentDocument, domainRuleTimelineToRichContentDocument, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, escapePraxisExportCell, evaluateFieldAccess, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getFormColumnFieldNames, getFormLayoutFieldNames, getGlobalActionCatalog, getGlobalActionPayloadActualType, getGlobalActionPayloadTypeIssue, getGlobalActionUiSchema, getMissingGlobalActionPayloadKeys, getPraxisTableCellVisualizationConstraint, getPraxisTableCellVisualizationGuidance, getReferencedFieldMetadata, getRequiredGlobalActionPayloadKeys, getTextTransformer, hasMeaningfulGlobalActionPayloadValue, hasPraxisCollectionExportArtifact, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isDomainRuleSnapshotProblemResponse, isEditorialComponentMeta, isEntityLookupMultiplePayloadMode, isEntityLookupPayloadMode, isEntityLookupPayloadModeCompatible, isEntityLookupResultSelectable, isEntityLookupSinglePayloadMode, isFormLayoutItem, isGlobalActionRef, isInlineFilterControlType, isLookupDialogSize, isLookupFilterFieldType, isLookupFilterOperator, isPraxisI18nMessageDescriptor, isPraxisPresentationVisualizationTableSafe, isPraxisRuntimeGlobalActionEffect, isProgrammaticDateRangePreset, isRangeValidForFilter, isRequiredGlobalActionParamPayloadMissing, isRequiredGlobalActionPayloadMissing, isStaticDateRangePreset, isSurfaceNavigationError, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, materializeFormLayoutFromMetadata, materializeResourceIdentity, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, migrateLegacyCompositionLink, migrateLegacyCompositionLinks, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldAccessMetadata, normalizeFieldConstraints, normalizeFieldPresentation, normalizeFormConfig, normalizeFormLayoutItems, normalizeFormMetadata, normalizeGlobalActionRef$1 as normalizeGlobalActionRef, normalizeLayoutPolicy, normalizeLookupFilterRequest, normalizePath, normalizePraxisDataQueryContext, normalizePraxisEffectPolicy, normalizePraxisPresentationVisualization, normalizePraxisQueryFilterExpression, normalizePraxisQueryFilterNode, normalizeReactiveDeterminations, normalizeResourceAvailabilityReasonCode, normalizeResourceIdentityContract, normalizeStart, normalizeSurfaceOperationContext, normalizeUnknownError, normalizeWidgetEventPath, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, projectComponentAuthoringManifest, projectGroupedCommandPartialRows, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisCollectionExportProvider, providePraxisDynamicPageMetadata, providePraxisEnterpriseRuntimeContext, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpCollectionExportProvider, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisIconDefaults, providePraxisJsonLogicOperator, providePraxisJsonLogicOperatorOverride, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRelatedResourceOutletMetadata, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, readPraxisExportValue, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, registerPraxisRuntimeComponentObservation, removeDiacritics, renderPraxisPresentationVisualizationHtml, reportTelemetryHookFactory, requiredCheckedValidator, requiredPresenceValidator, resolveBuiltinPresets, resolveColumnTypeFromFieldDefinition, resolveControlTypeAlias, resolveDateRangeShortcutPreset, resolveDateRangeShortcutPresets, resolveDefaultValuePresentationFormat, resolveEntityLookupPayloadMode, resolveFieldPresentation, resolveGroupedCommandPartialRowSpans, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisCollectionExportItems, resolvePraxisExportFields, resolvePraxisExportScope, resolvePraxisFilterCriteria, resolvePraxisI18nDocument, resolveResourceAvailabilityReasonKey, resolveResourceIdentityContract, resolveSpan, resolveTextMaskFormat, resolveTextMaskFormatFromFieldDefinition, resolveValuePresentation, resolveValuePresentationLocale, serializeEntityLookupValueForPayload, serializeOptionSourceFilterRequest, serializePraxisCollectionToCsv, serializePraxisCollectionToExcel, serializePraxisCollectionToJson, slugify, staticDateRangePresetToPreset, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateSurfaceNavigationRejected, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, validateGlobalActionRef, validateGlobalActionRefs, withFormConfigSections, withMessage, withPraxisHttpLoading };
46688
+ export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, COMPONENT_METADATA_REGISTRY_I18N_CONFIG, COMPONENT_METADATA_REGISTRY_I18N_NAMESPACE, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentAuthoringManifestProjectionError, ComponentKeyService, ComponentMetadataRegistry, ComponentRuntimeProfileService, CompositionRuntimeFacade, CompositionValidatorService, ConsoleLoggerSink, CrudOperationResolutionService, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_JSON_LOGIC_OPERATORS, DEFAULT_TABLE_CONFIG, DOMAIN_CATALOG_COMPONENT_CONTEXT_PACK, DOMAIN_CATALOG_CONTEXT_HINT_SCHEMA_VERSION, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DomainCatalogService, DomainKnowledgeService, DomainRuleService, DynamicFormService, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, EnterpriseRuntimeContextService, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NestedPortCatalogService, NestedWidgetConfigAccessor, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_ACTION_CONTROL_DEFAULTS, PRAXIS_ACTION_CONTROL_VARS, PRAXIS_COLLECTION_EXPORT_HTTP_OPTIONS, PRAXIS_COLLECTION_EXPORT_PROVIDER, PRAXIS_COLLECTION_SEARCH_DEFAULTS, PRAXIS_COLLECTION_SEARCH_VARS, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_EXPORT_SECURITY_POLICY, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_OPTIONS, PRAXIS_ENTERPRISE_RUNTIME_CONTEXT_READY, PRAXIS_EXPORT_FORMULA_PREFIXES, PRAXIS_EXPORT_SECURITY_POLICY, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_JSON_LOGIC_OPERATORS, PRAXIS_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_QUERY_FILTER_EXPRESSION_SCHEMA_VERSION, PRAXIS_RELATED_RESOURCE_OUTLET_AUTHORING_MANIFEST, PRAXIS_RELATED_RESOURCE_OUTLET_COMPONENT_METADATA, PRAXIS_RELATED_RESOURCE_OUTLET_PORTS, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TABLE_DETAIL_INLINE_NODE_RESOLVERS, PRAXIS_TABLE_DETAIL_INLINE_RENDERERS, PRAXIS_TABLE_DETAIL_RESOURCE_RESOLVER, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_THEME_SURFACE_DEFAULTS, PRAXIS_THEME_SURFACE_VARS, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCollectionExportService, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisHttpCollectionExportProvider, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, PraxisIconPickerComponent, PraxisJsonLogicError, PraxisJsonLogicService, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRelatedResourceOutletComponent, PraxisRelatedResourceOutletConfigEditorComponent, PraxisResourceIdentityComponent, PraxisRichTextBlockComponent, PraxisRuntimeComponentObservationRegistryService, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RelatedResourceSurfaceResolverService, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceRecordOpenError, ResourceRecordOpenService, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, SURFACE_DRAWER_CONTENT_DATA, SURFACE_DRAWER_REF, SURFACE_NAVIGATION_I18N_CONFIG, SURFACE_NAVIGATION_I18N_NAMESPACE, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceNavigationError, SurfaceOpenActionEditorComponent, SurfaceOpenMaterializerService, SurfaceOutletRegistryService, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageCompositionFactory, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, assertPraxisCollectionExportArtifact, assertPraxisRuntimeComponentObservationSerializable, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildPraxisActionControlCss, buildPraxisCollectionSearchCss, buildPraxisEffectDistinctKey, buildPraxisLayerScaleCss, buildPraxisThemeSurfaceCss, buildSchemaId, buildSchemaIdStorageKeySegment, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, classifyEntityLookupResult, clonePraxisRuntimeComponentObservation, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createEmptyRichContentDocument, createFieldLayoutItem, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, domainKnowledgeTimelineToRichContentDocument, domainRuleTimelineToRichContentDocument, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, escapePraxisExportCell, evaluateFieldAccess, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getFormColumnFieldNames, getFormLayoutFieldNames, getGlobalActionCatalog, getGlobalActionPayloadActualType, getGlobalActionPayloadTypeIssue, getGlobalActionProviderEvidence, getGlobalActionUiSchema, getMissingGlobalActionPayloadKeys, getPraxisTableCellVisualizationConstraint, getPraxisTableCellVisualizationGuidance, getReferencedFieldMetadata, getRequiredGlobalActionPayloadKeys, getTextTransformer, hasMeaningfulGlobalActionPayloadValue, hasPraxisCollectionExportArtifact, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isDomainRuleSnapshotProblemResponse, isEditorialComponentMeta, isEntityLookupMultiplePayloadMode, isEntityLookupPayloadMode, isEntityLookupPayloadModeCompatible, isEntityLookupResultSelectable, isEntityLookupSinglePayloadMode, isFormLayoutItem, isGlobalActionProviderOperational, isGlobalActionRef, isInlineFilterControlType, isLookupDialogSize, isLookupFilterFieldType, isLookupFilterOperator, isPraxisI18nMessageDescriptor, isPraxisPresentationVisualizationTableSafe, isPraxisRuntimeGlobalActionEffect, isProgrammaticDateRangePreset, isRangeValidForFilter, isRequiredGlobalActionParamPayloadMissing, isRequiredGlobalActionPayloadMissing, isStaticDateRangePreset, isSurfaceNavigationError, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, markGlobalActionProviderOperational, matchFieldValidator, materializeFormLayoutFromMetadata, materializeResourceIdentity, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, migrateLegacyCompositionLink, migrateLegacyCompositionLinks, minWordsValidator, nestedPortPathIdentity, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldAccessMetadata, normalizeFieldConstraints, normalizeFieldPresentation, normalizeFormConfig, normalizeFormLayoutItems, normalizeFormMetadata, normalizeGlobalActionRef$1 as normalizeGlobalActionRef, normalizeLayoutPolicy, normalizeLookupFilterRequest, normalizePath, normalizePraxisDataQueryContext, normalizePraxisEffectPolicy, normalizePraxisPresentationVisualization, normalizePraxisQueryFilterExpression, normalizePraxisQueryFilterNode, normalizeReactiveDeterminations, normalizeResourceAvailabilityReasonCode, normalizeResourceIdentityContract, normalizeStart, normalizeSurfaceOperationContext, normalizeUnknownError, normalizeWidgetEventPath, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, projectComponentAuthoringManifest, projectGroupedCommandPartialRows, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisCollectionExportProvider, providePraxisDynamicPageMetadata, providePraxisEnterpriseRuntimeContext, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpCollectionExportProvider, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisIconDefaults, providePraxisJsonLogicOperator, providePraxisJsonLogicOperatorOverride, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRelatedResourceOutletMetadata, providePraxisRichTextBlockMetadata, providePraxisTelemetry, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, readPraxisExportValue, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, registerPraxisRuntimeComponentObservation, removeDiacritics, renderPraxisPresentationVisualizationHtml, reportTelemetryHookFactory, requiredCheckedValidator, requiredPresenceValidator, resolveBuiltinPresets, resolveColumnTypeFromFieldDefinition, resolveControlTypeAlias, resolveDateRangeShortcutPreset, resolveDateRangeShortcutPresets, resolveDefaultValuePresentationFormat, resolveEntityLookupPayloadMode, resolveFieldPresentation, resolveGroupedCommandPartialRowSpans, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisCollectionExportItems, resolvePraxisExportFields, resolvePraxisExportScope, resolvePraxisFilterCriteria, resolvePraxisI18nDocument, resolveResourceAvailabilityReasonKey, resolveResourceIdentityContract, resolveSpan, resolveTextMaskFormat, resolveTextMaskFormatFromFieldDefinition, resolveValuePresentation, resolveValuePresentationLocale, serializeEntityLookupValueForPayload, serializeOptionSourceFilterRequest, serializePraxisCollectionToCsv, serializePraxisCollectionToExcel, serializePraxisCollectionToJson, slugify, staticDateRangePresetToPreset, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateSurfaceNavigationRejected, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, validateGlobalActionRef, validateGlobalActionRefs, withFormConfigSections, withMessage, withPraxisHttpLoading };