valtech-components 4.0.178 → 4.0.179
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/organisms/organization-view/organization-view.component.mjs +20 -28
- package/esm2022/lib/components/organisms/organization-view/organization-view.i18n.mjs +5 -3
- package/esm2022/lib/services/auth/oauth.service.mjs +140 -16
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +161 -44
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/organization-view/organization-view.component.d.ts +2 -1
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/lib/services/firebase/firebase-messaging-sw.js +145 -0
|
@@ -56,7 +56,7 @@ import { BrowserMultiFormatReader } from '@zxing/browser';
|
|
|
56
56
|
* Current version of valtech-components.
|
|
57
57
|
* This is automatically updated during the publish process.
|
|
58
58
|
*/
|
|
59
|
-
const VERSION = '4.0.
|
|
59
|
+
const VERSION = '4.0.179';
|
|
60
60
|
|
|
61
61
|
// Control de estado de refresco (singleton a nivel de módulo)
|
|
62
62
|
let isRefreshing = false;
|
|
@@ -6587,21 +6587,145 @@ class OAuthService {
|
|
|
6587
6587
|
this.clearLocalStorageFallback();
|
|
6588
6588
|
const nonce = this.generateNonce();
|
|
6589
6589
|
this.expectedNonce = nonce;
|
|
6590
|
-
//
|
|
6591
|
-
//
|
|
6592
|
-
|
|
6593
|
-
// entregan, y popup.closed queda bloqueado ("COOP policy would block the
|
|
6594
|
-
// window.closed call") → ni siquiera dispara el cancel: la ventana principal
|
|
6595
|
-
// espera para siempre sin redirigir. Navegamos la VENTANA COMPLETA al /start;
|
|
6596
|
-
// al volver, OAuthCallbackComponent corre como ventana principal (redirect_uri
|
|
6597
|
-
// SIN popup=true) y completa la sesión vía completeInMainWindow → navega al
|
|
6598
|
-
// home. Sin popup = sin COOP = sin cuelgue. (El link-flow sigue por popup.)
|
|
6599
|
-
const redirectUri = `${window.location.origin}/auth/oauth/callback`;
|
|
6590
|
+
// popup=true sobrevive el bounce cross-origin (Google/MS borran window.name
|
|
6591
|
+
// por privacidad). El backend lo reenvía en el redirect final vía appendParams.
|
|
6592
|
+
const redirectUri = `${window.location.origin}/auth/oauth/callback?popup=true`;
|
|
6600
6593
|
const startUrl = `${this.config?.apiUrl}/v2/auth/oauth/${provider}/start?redirect_uri=${encodeURIComponent(redirectUri)}&client_nonce=${encodeURIComponent(nonce)}`;
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6594
|
+
// Abrir popup centrado
|
|
6595
|
+
const width = 500;
|
|
6596
|
+
const height = 600;
|
|
6597
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
6598
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
6599
|
+
const features = `width=${width},height=${height},left=${left},top=${top},popup=yes`;
|
|
6600
|
+
this.popup = window.open(startUrl, 'oauth', features);
|
|
6601
|
+
if (!this.popup) {
|
|
6602
|
+
observer.error({
|
|
6603
|
+
code: 'POPUP_BLOCKED',
|
|
6604
|
+
message: 'El navegador bloqueó la ventana emergente. Por favor, permite popups para este sitio.',
|
|
6605
|
+
});
|
|
6606
|
+
return () => { };
|
|
6607
|
+
}
|
|
6608
|
+
// Escuchar mensajes del popup
|
|
6609
|
+
this.messageHandler = (event) => {
|
|
6610
|
+
// Validar origen
|
|
6611
|
+
if (event.origin !== window.location.origin) {
|
|
6612
|
+
return;
|
|
6613
|
+
}
|
|
6614
|
+
// Validar tipo de mensaje
|
|
6615
|
+
const data = event.data;
|
|
6616
|
+
if (data?.type !== 'oauth-callback') {
|
|
6617
|
+
return;
|
|
6618
|
+
}
|
|
6619
|
+
// Verificar el nonce del flujo (M-07): si no coincide, no es nuestro
|
|
6620
|
+
// callback → ignorar (no consumir el observable).
|
|
6621
|
+
if (!this.isNonceValid(data)) {
|
|
6622
|
+
return;
|
|
6623
|
+
}
|
|
6624
|
+
// Limpiar
|
|
6625
|
+
this.cleanup();
|
|
6626
|
+
// Emitir resultado dentro de NgZone para trigger change detection
|
|
6627
|
+
this.ngZone.run(() => {
|
|
6628
|
+
if (data.error) {
|
|
6629
|
+
observer.error(data.error);
|
|
6630
|
+
}
|
|
6631
|
+
else if (data.tokens) {
|
|
6632
|
+
observer.next(data.tokens);
|
|
6633
|
+
observer.complete();
|
|
6634
|
+
}
|
|
6635
|
+
else {
|
|
6636
|
+
observer.error({
|
|
6637
|
+
code: 'INVALID_RESPONSE',
|
|
6638
|
+
message: 'Respuesta inválida del servidor de autenticación',
|
|
6639
|
+
});
|
|
6640
|
+
}
|
|
6641
|
+
});
|
|
6642
|
+
};
|
|
6643
|
+
window.addEventListener('message', this.messageHandler);
|
|
6644
|
+
// BroadcastChannel: canal adicional immune a COOP (funciona entre misma
|
|
6645
|
+
// origin sin importar el browsing context group). Es el canal más fiable
|
|
6646
|
+
// cuando COOP sever el link opener→popup al pasar por Google/MS.
|
|
6647
|
+
try {
|
|
6648
|
+
this.broadcastChannel = new BroadcastChannel('valtech-oauth-callback');
|
|
6649
|
+
this.broadcastChannel.onmessage = (event) => {
|
|
6650
|
+
const data = event.data;
|
|
6651
|
+
if (data?.type !== 'oauth-callback')
|
|
6652
|
+
return;
|
|
6653
|
+
if (!this.isNonceValid(data))
|
|
6654
|
+
return;
|
|
6655
|
+
this.clearLocalStorageFallback();
|
|
6656
|
+
this.cleanup();
|
|
6657
|
+
this.ngZone.run(() => {
|
|
6658
|
+
if (data.error) {
|
|
6659
|
+
observer.error(data.error);
|
|
6660
|
+
}
|
|
6661
|
+
else if (data.tokens) {
|
|
6662
|
+
observer.next(data.tokens);
|
|
6663
|
+
observer.complete();
|
|
6664
|
+
}
|
|
6665
|
+
else {
|
|
6666
|
+
observer.error({
|
|
6667
|
+
code: 'INVALID_RESPONSE',
|
|
6668
|
+
message: 'Respuesta inválida del servidor de autenticación',
|
|
6669
|
+
});
|
|
6670
|
+
}
|
|
6671
|
+
});
|
|
6672
|
+
};
|
|
6673
|
+
}
|
|
6674
|
+
catch {
|
|
6675
|
+
// BroadcastChannel no disponible (contextos muy restringidos) — ignorar
|
|
6676
|
+
}
|
|
6677
|
+
// Polling de localStorage (COOP workaround - no podemos detectar popup.closed)
|
|
6678
|
+
// También verifica si el popup se cerró manualmente
|
|
6679
|
+
this.checkClosedInterval = setInterval(() => {
|
|
6680
|
+
// Primero verificar localStorage (funciona aunque COOP bloquee todo)
|
|
6681
|
+
const storedData = this.checkLocalStorageFallback();
|
|
6682
|
+
if (storedData) {
|
|
6683
|
+
this.cleanup();
|
|
6684
|
+
this.ngZone.run(() => {
|
|
6685
|
+
if (storedData.error) {
|
|
6686
|
+
observer.error(storedData.error);
|
|
6687
|
+
}
|
|
6688
|
+
else if (storedData.tokens) {
|
|
6689
|
+
// Gate de diagnóstico: la metadata de tokens (keys, presencia y
|
|
6690
|
+
// longitud del firebaseToken) no debe filtrarse a la consola en
|
|
6691
|
+
// producción (L4 del audit). Solo en dev.
|
|
6692
|
+
if (isDevMode()) {
|
|
6693
|
+
console.log('[OAuthService] Retrieved tokens from localStorage fallback', {
|
|
6694
|
+
keys: Object.keys(storedData.tokens),
|
|
6695
|
+
hasFirebaseToken: !!storedData.tokens.firebaseToken,
|
|
6696
|
+
firebaseTokenLength: storedData.tokens.firebaseToken?.length ?? 0,
|
|
6697
|
+
});
|
|
6698
|
+
}
|
|
6699
|
+
observer.next(storedData.tokens);
|
|
6700
|
+
observer.complete();
|
|
6701
|
+
}
|
|
6702
|
+
else {
|
|
6703
|
+
observer.error({
|
|
6704
|
+
code: 'INVALID_RESPONSE',
|
|
6705
|
+
message: 'Respuesta inválida del servidor de autenticación',
|
|
6706
|
+
});
|
|
6707
|
+
}
|
|
6708
|
+
});
|
|
6709
|
+
return;
|
|
6710
|
+
}
|
|
6711
|
+
// Intentar verificar si popup se cerró (puede fallar por COOP)
|
|
6712
|
+
try {
|
|
6713
|
+
if (this.popup?.closed) {
|
|
6714
|
+
this.cleanup();
|
|
6715
|
+
this.ngZone.run(() => {
|
|
6716
|
+
observer.error({
|
|
6717
|
+
code: 'POPUP_CLOSED',
|
|
6718
|
+
message: 'Se cerró la ventana de autenticación',
|
|
6719
|
+
});
|
|
6720
|
+
});
|
|
6721
|
+
}
|
|
6722
|
+
}
|
|
6723
|
+
catch {
|
|
6724
|
+
// COOP bloquea acceso a popup.closed - ignorar y seguir con polling
|
|
6725
|
+
}
|
|
6726
|
+
}, 300);
|
|
6727
|
+
// Cleanup cuando el observable se destruye
|
|
6728
|
+
return () => this.cleanup();
|
|
6605
6729
|
});
|
|
6606
6730
|
}
|
|
6607
6731
|
/**
|
|
@@ -54106,7 +54230,8 @@ const ORGANIZATION_VIEW_I18N = {
|
|
|
54106
54230
|
apiKeysFeaturePermsDesc: 'Cada key lleva solo los permisos que tú le asignes — concede el mínimo.',
|
|
54107
54231
|
apiKeysFeatureSecretTitle: 'Secreto único',
|
|
54108
54232
|
apiKeysFeatureSecretDesc: 'El secreto se muestra una sola vez. Guárdalo en un gestor de secretos.',
|
|
54109
|
-
|
|
54233
|
+
activeOrgTitle: 'Organización activa',
|
|
54234
|
+
switchOrgCta: 'Cambiar',
|
|
54110
54235
|
orgsMoreInfo: 'Aprender más sobre organizaciones',
|
|
54111
54236
|
orgsInfoTitle: '¿Qué son las organizaciones?',
|
|
54112
54237
|
orgsInfoSubtitle: 'Todo lo que necesitas saber',
|
|
@@ -54205,7 +54330,8 @@ const ORGANIZATION_VIEW_I18N = {
|
|
|
54205
54330
|
apiKeysFeaturePermsDesc: 'Each key carries only the permissions you assign — grant the minimum.',
|
|
54206
54331
|
apiKeysFeatureSecretTitle: 'One-time secret',
|
|
54207
54332
|
apiKeysFeatureSecretDesc: 'The secret is shown only once. Store it in a secret manager.',
|
|
54208
|
-
|
|
54333
|
+
activeOrgTitle: 'Active organization',
|
|
54334
|
+
switchOrgCta: 'Switch',
|
|
54209
54335
|
orgsMoreInfo: 'Learn more about organizations',
|
|
54210
54336
|
orgsInfoTitle: 'What are organizations?',
|
|
54211
54337
|
orgsInfoSubtitle: 'Everything you need to know',
|
|
@@ -54397,14 +54523,18 @@ class OrganizationViewComponent {
|
|
|
54397
54523
|
return this.tt('planEnterprise');
|
|
54398
54524
|
return this.tt('planFree');
|
|
54399
54525
|
});
|
|
54400
|
-
this.
|
|
54401
|
-
|
|
54402
|
-
|
|
54403
|
-
|
|
54404
|
-
|
|
54405
|
-
|
|
54406
|
-
|
|
54407
|
-
|
|
54526
|
+
this.switchOrgSectionProps = computed(() => ({
|
|
54527
|
+
title: this.tt('activeOrgTitle'),
|
|
54528
|
+
action: {
|
|
54529
|
+
text: this.tt('switchOrgCta'),
|
|
54530
|
+
color: 'dark',
|
|
54531
|
+
fill: 'outline',
|
|
54532
|
+
size: 'small',
|
|
54533
|
+
shape: 'round',
|
|
54534
|
+
type: 'button',
|
|
54535
|
+
token: 'org-switch',
|
|
54536
|
+
state: ComponentStates.ENABLED,
|
|
54537
|
+
},
|
|
54408
54538
|
}));
|
|
54409
54539
|
this.editButtonProps = computed(() => ({
|
|
54410
54540
|
text: this.tt('editCta'),
|
|
@@ -54923,15 +55053,8 @@ class OrganizationViewComponent {
|
|
|
54923
55053
|
content: pageDescription(),
|
|
54924
55054
|
}"
|
|
54925
55055
|
/>
|
|
54926
|
-
<!-- "
|
|
54927
|
-
|
|
54928
|
-
<button class="org-more-info-link" type="button" (click)="onOrgInfo()">
|
|
54929
|
-
{{ tt('orgsMoreInfo') }}
|
|
54930
|
-
</button>
|
|
54931
|
-
<!-- Cambiar de organización activa. -->
|
|
54932
|
-
<div class="org-switch-row">
|
|
54933
|
-
<val-button [props]="switchOrgButtonProps()" (onClick)="onSwitchOrg()" />
|
|
54934
|
-
</div>
|
|
55056
|
+
<!-- Sección "Organización activa" con botón Cambiar a la derecha. -->
|
|
55057
|
+
<val-section-header [props]="switchOrgSectionProps()" (actionClick)="onSwitchOrg()" />
|
|
54935
55058
|
</header>
|
|
54936
55059
|
|
|
54937
55060
|
@if (resolvedConfig().showInfo) {
|
|
@@ -55233,7 +55356,7 @@ class OrganizationViewComponent {
|
|
|
55233
55356
|
(created)="onOrgCreated($event)"
|
|
55234
55357
|
/>
|
|
55235
55358
|
</div>
|
|
55236
|
-
`, isInline: true, styles: [".page{padding:16px 0;max-width:720px;margin:0 auto}.org-more-info-link{background:none;border:none;padding:4px 0;margin-top:4px;font-size:13px;font-weight:600;color:var(--ion-color-primary, #7026df);cursor:pointer;text-align:left}.page-header{margin-bottom:16px}.settings-section{padding:16px 0}.settings-section+.settings-section{border-top:1px solid var(--val-border-color, rgba(0, 0, 0, .08))}.section-header-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.section-body{display:flex;flex-direction:column;gap:10px}.row-actions{margin-top:12px}.row-actions--gap{display:flex;gap:8px}.invite-cta{display:flex;flex-direction:column;gap:16px}.invite-cta__text{display:flex;flex-direction:column;gap:4px}.invite-cta__actions{display:flex;gap:12px;flex-wrap:wrap}.org-info-card{border-radius:14px;background:var(--ion-color-light, #f4f5f8);overflow:hidden}.org-info-logo{display:flex;justify-content:center;padding:8px 0 16px}.org-logo-img{width:80px;height:80px;border-radius:50%;object-fit:cover;border:2px solid var(--ion-color-light)}:host-context(body.dark) .org-info-card,:host-context(html.ion-palette-dark) .org-info-card,:host-context([data-theme=\"dark\"]) .org-info-card{background:#ffffff0d}.org-info-field{padding:12px 16px;display:flex;flex-direction:column;gap:4px;border-bottom:1px solid var(--val-border-color, rgba(0, 0, 0, .06))}.org-info-field:last-child{border-bottom:none}.org-info-label{font-size:.74rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--ion-color-medium)}.org-info-value{font-size:.95rem;font-weight:500;color:var(--ion-color-dark)}.org-info-value--muted{color:var(--ion-color-medium);font-weight:400}.plan-badge{display:inline-block;font-size:.78rem;font-weight:700;padding:3px 10px;border-radius:20px;width:fit-content}.plan-badge--free{background:var(--ion-color-light-shade, #d7d8da);color:var(--ion-color-dark)}.plan-badge--pro{background:var(--ion-color-primary);color:#fff}.plan-badge--enterprise{background:#f5c542;color:#222}.members-list{display:flex;flex-direction:column;gap:8px}.members-show-more{background:none;border:none;color:var(--ion-color-primary);font-size:14px;font-weight:500;cursor:pointer;padding:8px 0}.rbac-debug{opacity:.7}.rbac-debug__body{display:flex;flex-direction:column;gap:6px;font-family:monospace;font-size:.78rem}.rbac-debug__row{display:flex;gap:8px;align-items:flex-start}.rbac-debug__label{color:var(--ion-color-medium);min-width:72px;flex-shrink:0}.rbac-debug__value{color:var(--ion-color-dark);word-break:break-all}.rbac-debug__value--perms{color:var(--ion-color-medium)}.section-title-danger{display:flex;align-items:center;gap:8px;margin-bottom:12px}.section-title-danger val-title{display:block;margin:0}.danger-icon{display:block;font-size:1.125rem;color:var(--ion-color-warning-shade, #d4a017);flex-shrink:0}\n"], dependencies: [{ kind: "component", type: CreateOrgModalComponent, selector: "val-create-org-modal", inputs: ["i18nNamespace", "isOpen"], outputs: ["dismissed", "created"] }, { kind: "component", type: CtaCardComponent, selector: "val-cta-card", inputs: ["props"], outputs: ["onAction"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: EmptyStateComponent, selector: "val-empty-state", inputs: ["props"] }, { kind: "directive", type: HasPermissionDirective, selector: "[valHasPermission]", inputs: ["valHasPermission"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: SkeletonLayoutComponent, selector: "val-skeleton-layout", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: MemberCardComponent, selector: "val-member-card", inputs: ["props"], outputs: ["onAction"] }, { kind: "component", type: PermissionsModalComponent, selector: "val-permissions-modal", inputs: ["isOpen", "config"], outputs: ["dismissed"] }] }); }
|
|
55359
|
+
`, isInline: true, styles: [".page{padding:16px 0;max-width:720px;margin:0 auto}.org-more-info-link{background:none;border:none;padding:4px 0;margin-top:4px;font-size:13px;font-weight:600;color:var(--ion-color-primary, #7026df);cursor:pointer;text-align:left}.page-header{margin-bottom:16px}.settings-section{padding:16px 0}.settings-section+.settings-section{border-top:1px solid var(--val-border-color, rgba(0, 0, 0, .08))}.section-header-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.section-body{display:flex;flex-direction:column;gap:10px}.row-actions{margin-top:12px}.row-actions--gap{display:flex;gap:8px}.invite-cta{display:flex;flex-direction:column;gap:16px}.invite-cta__text{display:flex;flex-direction:column;gap:4px}.invite-cta__actions{display:flex;gap:12px;flex-wrap:wrap}.org-info-card{border-radius:14px;background:var(--ion-color-light, #f4f5f8);overflow:hidden}.org-info-logo{display:flex;justify-content:center;padding:8px 0 16px}.org-logo-img{width:80px;height:80px;border-radius:50%;object-fit:cover;border:2px solid var(--ion-color-light)}:host-context(body.dark) .org-info-card,:host-context(html.ion-palette-dark) .org-info-card,:host-context([data-theme=\"dark\"]) .org-info-card{background:#ffffff0d}.org-info-field{padding:12px 16px;display:flex;flex-direction:column;gap:4px;border-bottom:1px solid var(--val-border-color, rgba(0, 0, 0, .06))}.org-info-field:last-child{border-bottom:none}.org-info-label{font-size:.74rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--ion-color-medium)}.org-info-value{font-size:.95rem;font-weight:500;color:var(--ion-color-dark)}.org-info-value--muted{color:var(--ion-color-medium);font-weight:400}.plan-badge{display:inline-block;font-size:.78rem;font-weight:700;padding:3px 10px;border-radius:20px;width:fit-content}.plan-badge--free{background:var(--ion-color-light-shade, #d7d8da);color:var(--ion-color-dark)}.plan-badge--pro{background:var(--ion-color-primary);color:#fff}.plan-badge--enterprise{background:#f5c542;color:#222}.members-list{display:flex;flex-direction:column;gap:8px}.members-show-more{background:none;border:none;color:var(--ion-color-primary);font-size:14px;font-weight:500;cursor:pointer;padding:8px 0}.rbac-debug{opacity:.7}.rbac-debug__body{display:flex;flex-direction:column;gap:6px;font-family:monospace;font-size:.78rem}.rbac-debug__row{display:flex;gap:8px;align-items:flex-start}.rbac-debug__label{color:var(--ion-color-medium);min-width:72px;flex-shrink:0}.rbac-debug__value{color:var(--ion-color-dark);word-break:break-all}.rbac-debug__value--perms{color:var(--ion-color-medium)}.section-title-danger{display:flex;align-items:center;gap:8px;margin-bottom:12px}.section-title-danger val-title{display:block;margin:0}.danger-icon{display:block;font-size:1.125rem;color:var(--ion-color-warning-shade, #d4a017);flex-shrink:0}\n"], dependencies: [{ kind: "component", type: CreateOrgModalComponent, selector: "val-create-org-modal", inputs: ["i18nNamespace", "isOpen"], outputs: ["dismissed", "created"] }, { kind: "component", type: CtaCardComponent, selector: "val-cta-card", inputs: ["props"], outputs: ["onAction"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: EmptyStateComponent, selector: "val-empty-state", inputs: ["props"] }, { kind: "directive", type: HasPermissionDirective, selector: "[valHasPermission]", inputs: ["valHasPermission"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: SkeletonLayoutComponent, selector: "val-skeleton-layout", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextComponent, selector: "val-text", inputs: ["props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: MemberCardComponent, selector: "val-member-card", inputs: ["props"], outputs: ["onAction"] }, { kind: "component", type: PermissionsModalComponent, selector: "val-permissions-modal", inputs: ["isOpen", "config"], outputs: ["dismissed"] }, { kind: "component", type: SectionHeaderComponent, selector: "val-section-header", inputs: ["props"], outputs: ["actionClick"] }] }); }
|
|
55237
55360
|
}
|
|
55238
55361
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OrganizationViewComponent, decorators: [{
|
|
55239
55362
|
type: Component,
|
|
@@ -55253,6 +55376,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
55253
55376
|
TransferOwnershipModalComponent,
|
|
55254
55377
|
MemberImportModalComponent,
|
|
55255
55378
|
OrgInfoSheetComponent,
|
|
55379
|
+
SectionHeaderComponent,
|
|
55256
55380
|
SwitchOrgModalComponent,
|
|
55257
55381
|
], template: `
|
|
55258
55382
|
<div class="page">
|
|
@@ -55266,15 +55390,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
55266
55390
|
content: pageDescription(),
|
|
55267
55391
|
}"
|
|
55268
55392
|
/>
|
|
55269
|
-
<!-- "
|
|
55270
|
-
|
|
55271
|
-
<button class="org-more-info-link" type="button" (click)="onOrgInfo()">
|
|
55272
|
-
{{ tt('orgsMoreInfo') }}
|
|
55273
|
-
</button>
|
|
55274
|
-
<!-- Cambiar de organización activa. -->
|
|
55275
|
-
<div class="org-switch-row">
|
|
55276
|
-
<val-button [props]="switchOrgButtonProps()" (onClick)="onSwitchOrg()" />
|
|
55277
|
-
</div>
|
|
55393
|
+
<!-- Sección "Organización activa" con botón Cambiar a la derecha. -->
|
|
55394
|
+
<val-section-header [props]="switchOrgSectionProps()" (actionClick)="onSwitchOrg()" />
|
|
55278
55395
|
</header>
|
|
55279
55396
|
|
|
55280
55397
|
@if (resolvedConfig().showInfo) {
|