@idp.global/catalog 2.2.0 → 3.1.0
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/changelog.md +21 -0
- package/dist_bundle/bundle.js +1175 -436
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/idp-admin-shell.d.ts +30 -1
- package/dist_ts_web/elements/idp-admin-shell.js +261 -28
- package/dist_ts_web/elements/idp-admin-sidebar.js +6 -5
- package/dist_ts_web/elements/idp-invite-card.d.ts +39 -0
- package/dist_ts_web/elements/idp-invite-card.js +303 -0
- package/dist_ts_web/elements/idp-scim-token-panel.d.ts +43 -0
- package/dist_ts_web/elements/idp-scim-token-panel.js +361 -0
- package/dist_ts_web/elements/idp-sso-connection-form.d.ts +81 -0
- package/dist_ts_web/elements/idp-sso-connection-form.js +637 -0
- package/dist_ts_web/elements/index.d.ts +3 -0
- package/dist_ts_web/elements/index.js +4 -1
- package/package.json +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/idp-admin-shell.ts +237 -25
- package/ts_web/elements/idp-admin-sidebar.ts +5 -4
- package/ts_web/elements/idp-invite-card.ts +229 -0
- package/ts_web/elements/idp-scim-token-panel.ts +311 -0
- package/ts_web/elements/idp-sso-connection-form.ts +574 -0
- package/ts_web/elements/index.ts +3 -0
|
@@ -22,6 +22,7 @@ export * from './idp-signed-in-pill.js';
|
|
|
22
22
|
export * from './idp-app-pair.js';
|
|
23
23
|
export * from './idp-auth-card.js';
|
|
24
24
|
export * from './idp-consent-card.js';
|
|
25
|
+
export * from './idp-invite-card.js';
|
|
25
26
|
export * from './idp-approval-card.js';
|
|
26
27
|
export * from './idp-mobile-frame.js';
|
|
27
28
|
export * from './idp-inbox-preview.js';
|
|
@@ -34,3 +35,5 @@ export * from './idp-admin-shell.js';
|
|
|
34
35
|
export * from './idp-landing-hero.js';
|
|
35
36
|
export * from './idp-landing-page.js';
|
|
36
37
|
export * from './idp-mobile-showcase.js';
|
|
38
|
+
export * from './idp-sso-connection-form.js';
|
|
39
|
+
export * from './idp-scim-token-panel.js';
|
|
@@ -22,6 +22,7 @@ export * from './idp-signed-in-pill.js';
|
|
|
22
22
|
export * from './idp-app-pair.js';
|
|
23
23
|
export * from './idp-auth-card.js';
|
|
24
24
|
export * from './idp-consent-card.js';
|
|
25
|
+
export * from './idp-invite-card.js';
|
|
25
26
|
export * from './idp-approval-card.js';
|
|
26
27
|
export * from './idp-mobile-frame.js';
|
|
27
28
|
export * from './idp-inbox-preview.js';
|
|
@@ -34,4 +35,6 @@ export * from './idp-admin-shell.js';
|
|
|
34
35
|
export * from './idp-landing-hero.js';
|
|
35
36
|
export * from './idp-landing-page.js';
|
|
36
37
|
export * from './idp-mobile-showcase.js';
|
|
37
|
-
|
|
38
|
+
export * from './idp-sso-connection-form.js';
|
|
39
|
+
export * from './idp-scim-token-panel.js';
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c193ZWIvZWxlbWVudHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxlQUFlLENBQUM7QUFDOUIsY0FBYyxpQkFBaUIsQ0FBQztBQUNoQyxjQUFjLGdCQUFnQixDQUFDO0FBQy9CLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYywyQkFBMkIsQ0FBQztBQUMxQyxjQUFjLDZCQUE2QixDQUFDO0FBQzVDLGNBQWMsdUJBQXVCLENBQUM7QUFDdEMsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLDJCQUEyQixDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -8,8 +8,12 @@ import './idp-toggle.js';
|
|
|
8
8
|
import './idp-delegation-section.js';
|
|
9
9
|
import './idp-admin-sidebar.js';
|
|
10
10
|
import './idp-admin-overview.js';
|
|
11
|
+
import './idp-sso-connection-form.js';
|
|
12
|
+
import './idp-scim-token-panel.js';
|
|
11
13
|
import { idpAdminSharedStyles, renderAdminKpi, renderAdminStateCard, formatAdminTimeAgo, type TIdpAdminKpi } from './idp-admin-shared.js';
|
|
12
14
|
import type { IIdpDelegation, IIdpDelegationApp } from './idp-delegation-section.js';
|
|
15
|
+
import type { IIdpSsoConnectionItem, IIdpSsoSpDetails } from './idp-sso-connection-form.js';
|
|
16
|
+
import type { IIdpScimTokenItem } from './idp-scim-token-panel.js';
|
|
13
17
|
|
|
14
18
|
declare global {
|
|
15
19
|
interface HTMLElementTagNameMap {
|
|
@@ -27,6 +31,7 @@ export type TIdpAdminPage =
|
|
|
27
31
|
| 'org-settings'
|
|
28
32
|
| 'org-members'
|
|
29
33
|
| 'org-apps'
|
|
34
|
+
| 'org-sso'
|
|
30
35
|
| 'support'
|
|
31
36
|
| 'ga-users'
|
|
32
37
|
| 'ga-orgs'
|
|
@@ -89,6 +94,12 @@ export interface IIdpAdminGaUserActionEventDetail {
|
|
|
89
94
|
action: 'suspend' | 'unsuspend';
|
|
90
95
|
}
|
|
91
96
|
|
|
97
|
+
export interface IIdpAdminProfileUpdateEventDetail {
|
|
98
|
+
name: string;
|
|
99
|
+
username: string;
|
|
100
|
+
mobileNumber: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
92
103
|
export interface IIdpAdminGaOrgActionEventDetail {
|
|
93
104
|
orgId: string;
|
|
94
105
|
action: 'suspend' | 'unsuspend';
|
|
@@ -826,13 +837,88 @@ export class IdpAdminShell extends DeesElement {
|
|
|
826
837
|
.mapping-row .form-label {
|
|
827
838
|
margin-bottom: 4px;
|
|
828
839
|
}
|
|
840
|
+
.mobile-topbar {
|
|
841
|
+
display: none;
|
|
842
|
+
align-items: center;
|
|
843
|
+
gap: 10px;
|
|
844
|
+
padding: 10px 14px;
|
|
845
|
+
border-bottom: 1px solid var(--sh-border);
|
|
846
|
+
background: var(--sh-card);
|
|
847
|
+
position: sticky;
|
|
848
|
+
top: 0;
|
|
849
|
+
z-index: 40;
|
|
850
|
+
}
|
|
851
|
+
.mobile-topbar-title {
|
|
852
|
+
font-size: 13px;
|
|
853
|
+
font-weight: 650;
|
|
854
|
+
letter-spacing: -0.01em;
|
|
855
|
+
}
|
|
856
|
+
.mobile-nav-toggle,
|
|
857
|
+
.mobile-drawer-close {
|
|
858
|
+
display: inline-flex;
|
|
859
|
+
align-items: center;
|
|
860
|
+
justify-content: center;
|
|
861
|
+
width: 34px;
|
|
862
|
+
height: 34px;
|
|
863
|
+
border: 1px solid var(--sh-border);
|
|
864
|
+
border-radius: 9px;
|
|
865
|
+
background: var(--sh-card);
|
|
866
|
+
color: var(--sh-fg);
|
|
867
|
+
cursor: pointer;
|
|
868
|
+
}
|
|
869
|
+
.mobile-nav-toggle:focus-visible,
|
|
870
|
+
.mobile-drawer-close:focus-visible {
|
|
871
|
+
outline: 2px solid var(--sh-accent);
|
|
872
|
+
outline-offset: 2px;
|
|
873
|
+
}
|
|
874
|
+
.mobile-drawer-backdrop {
|
|
875
|
+
position: fixed;
|
|
876
|
+
inset: 0;
|
|
877
|
+
background: rgba(0, 0, 0, 0.42);
|
|
878
|
+
z-index: 60;
|
|
879
|
+
}
|
|
880
|
+
.mobile-drawer {
|
|
881
|
+
position: fixed;
|
|
882
|
+
top: 0;
|
|
883
|
+
left: 0;
|
|
884
|
+
bottom: 0;
|
|
885
|
+
width: min(300px, 86vw);
|
|
886
|
+
background: var(--sh-card);
|
|
887
|
+
border-right: 1px solid var(--sh-border);
|
|
888
|
+
z-index: 61;
|
|
889
|
+
overflow-y: auto;
|
|
890
|
+
animation: drawer-in 0.18s ease-out;
|
|
891
|
+
}
|
|
892
|
+
.mobile-drawer idp-admin-sidebar {
|
|
893
|
+
display: block;
|
|
894
|
+
}
|
|
895
|
+
.mobile-drawer-close {
|
|
896
|
+
position: absolute;
|
|
897
|
+
top: 10px;
|
|
898
|
+
right: 10px;
|
|
899
|
+
z-index: 62;
|
|
900
|
+
}
|
|
901
|
+
@keyframes drawer-in {
|
|
902
|
+
from {
|
|
903
|
+
transform: translateX(-24px);
|
|
904
|
+
opacity: 0;
|
|
905
|
+
}
|
|
906
|
+
to {
|
|
907
|
+
transform: translateX(0);
|
|
908
|
+
opacity: 1;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
829
911
|
@media (max-width: 1120px) {
|
|
830
912
|
.shell {
|
|
831
913
|
grid-template-columns: 1fr;
|
|
914
|
+
grid-template-rows: auto 1fr;
|
|
832
915
|
}
|
|
833
|
-
idp-admin-sidebar {
|
|
916
|
+
.shell > idp-admin-sidebar {
|
|
834
917
|
display: none;
|
|
835
918
|
}
|
|
919
|
+
.mobile-topbar {
|
|
920
|
+
display: flex;
|
|
921
|
+
}
|
|
836
922
|
}
|
|
837
923
|
@media (max-width: 720px) {
|
|
838
924
|
.mapping-row {
|
|
@@ -917,6 +1003,18 @@ export class IdpAdminShell extends DeesElement {
|
|
|
917
1003
|
@property({ type: Array })
|
|
918
1004
|
public accessor gaUsers: IIdpAdminGaUser[] = [];
|
|
919
1005
|
|
|
1006
|
+
@property({ type: Array })
|
|
1007
|
+
public accessor ssoConnections: IIdpSsoConnectionItem[] = [];
|
|
1008
|
+
|
|
1009
|
+
@property({ type: Object })
|
|
1010
|
+
public accessor ssoSpDetails: IIdpSsoSpDetails | null = null;
|
|
1011
|
+
|
|
1012
|
+
@property({ type: Array })
|
|
1013
|
+
public accessor scimTokens: IIdpScimTokenItem[] = [];
|
|
1014
|
+
|
|
1015
|
+
@property({ type: Object })
|
|
1016
|
+
public accessor scimCreatedToken: { label: string; plaintextToken: string } | null = null;
|
|
1017
|
+
|
|
920
1018
|
@property({ type: Object })
|
|
921
1019
|
public accessor overviewData: IIdpAdminOverviewData | null = null;
|
|
922
1020
|
|
|
@@ -926,6 +1024,20 @@ export class IdpAdminShell extends DeesElement {
|
|
|
926
1024
|
@property({ type: Array })
|
|
927
1025
|
public accessor delegations: IIdpDelegation[] = [];
|
|
928
1026
|
|
|
1027
|
+
/** enables editing of name/username/mobile on the profile page */
|
|
1028
|
+
@property({ type: Boolean })
|
|
1029
|
+
public accessor profileEditable = false;
|
|
1030
|
+
|
|
1031
|
+
/** host sets this while a profile update request is in flight */
|
|
1032
|
+
@property({ type: Boolean })
|
|
1033
|
+
public accessor profileSaving = false;
|
|
1034
|
+
|
|
1035
|
+
@state()
|
|
1036
|
+
private accessor profileDraft: { name: string; username: string; mobileNumber: string } | null = null;
|
|
1037
|
+
|
|
1038
|
+
@state()
|
|
1039
|
+
private accessor mobileNavOpen = false;
|
|
1040
|
+
|
|
929
1041
|
@state()
|
|
930
1042
|
private accessor logoutEverywhere = false;
|
|
931
1043
|
|
|
@@ -1319,6 +1431,22 @@ export class IdpAdminShell extends DeesElement {
|
|
|
1319
1431
|
await super.disconnectedCallback();
|
|
1320
1432
|
}
|
|
1321
1433
|
|
|
1434
|
+
protected override willUpdate(changedProperties: Map<PropertyKey, unknown>) {
|
|
1435
|
+
super.willUpdate(changedProperties);
|
|
1436
|
+
// a refreshed user means the host persisted (or reloaded) the profile
|
|
1437
|
+
if (changedProperties.has('user')) {
|
|
1438
|
+
this.profileDraft = null;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
protected override updated(changedProperties: Map<PropertyKey, unknown>) {
|
|
1443
|
+
super.updated(changedProperties);
|
|
1444
|
+
if (changedProperties.has('mobileNavOpen') && this.mobileNavOpen) {
|
|
1445
|
+
const closeButton = this.shadowRoot?.querySelector('.mobile-drawer-close') as HTMLElement | null;
|
|
1446
|
+
closeButton?.focus();
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1322
1450
|
private dispatchShellEvent<TDetail>(eventNameArg: string, detailArg: TDetail) {
|
|
1323
1451
|
this.dispatchEvent(new CustomEvent<TDetail>(eventNameArg, {
|
|
1324
1452
|
detail: detailArg,
|
|
@@ -1761,18 +1889,54 @@ export class IdpAdminShell extends DeesElement {
|
|
|
1761
1889
|
`;
|
|
1762
1890
|
}
|
|
1763
1891
|
|
|
1892
|
+
private getProfileDraft() {
|
|
1893
|
+
return (
|
|
1894
|
+
this.profileDraft || {
|
|
1895
|
+
name: this.user?.name || '',
|
|
1896
|
+
username: this.user?.username || this.user?.email?.split('@')[0] || '',
|
|
1897
|
+
mobileNumber: this.user?.mobileNumber || '',
|
|
1898
|
+
}
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
private setProfileDraftField(fieldArg: 'name' | 'username' | 'mobileNumber', eventArg: Event) {
|
|
1903
|
+
const value = (eventArg.target as HTMLInputElement).value;
|
|
1904
|
+
this.profileDraft = { ...this.getProfileDraft(), [fieldArg]: value };
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
private handleProfileSave() {
|
|
1908
|
+
const draft = this.getProfileDraft();
|
|
1909
|
+
this.dispatchShellEvent<IIdpAdminProfileUpdateEventDetail>('idp-admin-profile-update', {
|
|
1910
|
+
name: draft.name.trim(),
|
|
1911
|
+
username: draft.username.trim(),
|
|
1912
|
+
mobileNumber: draft.mobileNumber.trim(),
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1764
1916
|
private renderProfile(): TemplateResult {
|
|
1765
|
-
const username = this.user?.username || this.user?.email?.split('@')[0] || '';
|
|
1766
1917
|
const status = this.user?.status || 'active';
|
|
1918
|
+
const draft = this.getProfileDraft();
|
|
1919
|
+
const editable = this.profileEditable;
|
|
1920
|
+
const dirty =
|
|
1921
|
+
this.profileDraft !== null &&
|
|
1922
|
+
(draft.name !== (this.user?.name || '') ||
|
|
1923
|
+
draft.username !== (this.user?.username || this.user?.email?.split('@')[0] || '') ||
|
|
1924
|
+
draft.mobileNumber !== (this.user?.mobileNumber || ''));
|
|
1767
1925
|
return html`
|
|
1768
1926
|
${this.renderPageHeader('Profile', 'Your personal identity details visible to connected apps.')}
|
|
1769
1927
|
<div class="body narrow-body">
|
|
1770
|
-
${this.renderSectionCard('Avatar', 'Shown to apps that request your profile.', html`<div class="split-row" style="justify-content:flex-start"><span class="avatar" style="width:56px;height:56px;font-size:20px">${this.userInitials}</span><div><div class="section-title">${this.user?.name || 'Unknown User'}</div><div class="muted" style="margin-top:5px"
|
|
1928
|
+
${this.renderSectionCard('Avatar', 'Shown to apps that request your profile.', html`<div class="split-row" style="justify-content:flex-start"><span class="avatar" style="width:56px;height:56px;font-size:20px">${this.userInitials}</span><div><div class="section-title">${this.user?.name || 'Unknown User'}</div><div class="muted" style="margin-top:5px">${this.user?.email || ''}</div></div></div>`)}
|
|
1771
1929
|
${this.renderSectionCard('Personal information', '', html`
|
|
1772
|
-
${this.renderFormRow('Full name', '', html`<input class="input" .value=${
|
|
1773
|
-
${this.renderFormRow('Username', 'Used in your public profile URL', html`<div class="input-group"><span class="input-prefix">idp.global/user/</span><input class="input" .value=${username} disabled /></div>`)}
|
|
1774
|
-
${this.renderFormRow('Email', 'Primary address for login and notifications', html`<input class="input" .value=${this.user?.email || ''} disabled />`)}
|
|
1775
|
-
${this.renderFormRow('Mobile number', '
|
|
1930
|
+
${this.renderFormRow('Full name', '', html`<input class="input" .value=${draft.name} ?disabled=${!editable || this.profileSaving} @input=${(eventArg: Event) => this.setProfileDraftField('name', eventArg)} />`, true)}
|
|
1931
|
+
${this.renderFormRow('Username', 'Used in your public profile URL', html`<div class="input-group"><span class="input-prefix">idp.global/user/</span><input class="input" .value=${draft.username} ?disabled=${!editable || this.profileSaving} @input=${(eventArg: Event) => this.setProfileDraftField('username', eventArg)} /></div>`)}
|
|
1932
|
+
${this.renderFormRow('Email', 'Primary address for login and notifications - contact support to change it', html`<input class="input" .value=${this.user?.email || ''} disabled />`)}
|
|
1933
|
+
${this.renderFormRow('Mobile number', 'Optional contact number shown to connected apps', html`<input class="input" .value=${draft.mobileNumber} ?disabled=${!editable || this.profileSaving} @input=${(eventArg: Event) => this.setProfileDraftField('mobileNumber', eventArg)} />`)}
|
|
1934
|
+
${editable
|
|
1935
|
+
? html`<div class="split-row" style="justify-content:flex-end;gap:10px;margin-top:14px">
|
|
1936
|
+
<idp-button variant="outline" shape="rect" ?disabled=${!dirty || this.profileSaving} @click=${() => { this.profileDraft = null; }}>Reset</idp-button>
|
|
1937
|
+
<idp-button variant="accent" shape="rect" ?loading=${this.profileSaving} ?disabled=${!dirty} @click=${this.handleProfileSave}>Save changes</idp-button>
|
|
1938
|
+
</div>`
|
|
1939
|
+
: html``}
|
|
1776
1940
|
`)}
|
|
1777
1941
|
${this.renderSectionCard('Account status', '', html`<div class="split-row"><div><div class="section-title">Status</div><div class="muted">Your account is currently ${status}.</div></div><idp-badge variant=${status === 'active' ? 'ok' : status === 'suspended' ? 'error' : 'warn'}>${status}</idp-badge></div>${this.globalAdmin ? html`<div class="divider"></div><div class="split-row"><div><div class="section-title">Global admin</div><div class="muted">You have platform-wide administrative access.</div></div><idp-badge variant="accent">Admin</idp-badge></div>` : html``}`)}
|
|
1778
1942
|
${this.delegationApps.length
|
|
@@ -2220,6 +2384,25 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2220
2384
|
`;
|
|
2221
2385
|
}
|
|
2222
2386
|
|
|
2387
|
+
private renderOrgSso(): TemplateResult {
|
|
2388
|
+
return html`
|
|
2389
|
+
${this.renderPageHeader('SSO & Provisioning', 'Enterprise single sign-on and automated user provisioning for this organisation.')}
|
|
2390
|
+
<div class="body narrow-body">
|
|
2391
|
+
<div class="list-stack">
|
|
2392
|
+
<idp-sso-connection-form
|
|
2393
|
+
.connections=${this.ssoConnections}
|
|
2394
|
+
.spDetails=${this.ssoSpDetails}
|
|
2395
|
+
></idp-sso-connection-form>
|
|
2396
|
+
<idp-scim-token-panel
|
|
2397
|
+
.tokens=${this.scimTokens}
|
|
2398
|
+
.createdToken=${this.scimCreatedToken}
|
|
2399
|
+
scimBaseUrl=${this.ssoSpDetails?.scimBaseUrl || ''}
|
|
2400
|
+
></idp-scim-token-panel>
|
|
2401
|
+
</div>
|
|
2402
|
+
</div>
|
|
2403
|
+
`;
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2223
2406
|
private renderSupport(): TemplateResult {
|
|
2224
2407
|
const services = [
|
|
2225
2408
|
['Account Recovery', 'Lost access to your account or locked out of your organisation? Our team will verify your identity and restore access securely.', 'EUR149', 'per incident', 'key', '1-2 business days'],
|
|
@@ -2293,6 +2476,7 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2293
2476
|
const planVariant = (planArg: string): 'accent' | 'ok' | 'warn' | 'default' =>
|
|
2294
2477
|
planArg === 'Pro' ? 'accent' : planArg === 'Enterprise' ? 'ok' : planArg === 'Internal' ? 'warn' : 'default';
|
|
2295
2478
|
const hasAdminFields = this.orgs.some((orgArg) => orgArg.status || orgArg.plan);
|
|
2479
|
+
const hasMemberCounts = this.orgs.some((orgArg) => orgArg.memberCount !== undefined);
|
|
2296
2480
|
const orgRows = this.orgs.map((orgArg) => ({
|
|
2297
2481
|
cells: [
|
|
2298
2482
|
html`
|
|
@@ -2305,9 +2489,9 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2305
2489
|
</div>
|
|
2306
2490
|
`,
|
|
2307
2491
|
orgArg.slug || '-',
|
|
2492
|
+
...(hasMemberCounts ? [orgArg.memberCount !== undefined ? String(orgArg.memberCount) : '-'] : []),
|
|
2308
2493
|
...(hasAdminFields
|
|
2309
2494
|
? [
|
|
2310
|
-
orgArg.memberCount !== undefined ? String(orgArg.memberCount) : '-',
|
|
2311
2495
|
orgArg.plan ? html`<idp-badge variant=${planVariant(orgArg.plan)}>${orgArg.plan}</idp-badge>` : '-',
|
|
2312
2496
|
html`<idp-badge variant=${orgArg.status === 'suspended' ? 'error' : 'ok'}>${orgArg.status || 'active'}</idp-badge>`,
|
|
2313
2497
|
html`<button class="plain-button ghost" style="font-size:11px" @click=${() => this.dispatchShellEvent<IIdpAdminGaOrgActionEventDetail>('idp-admin-ga-org-action', { orgId: orgArg.id, action: orgArg.status === 'suspended' ? 'unsuspend' : 'suspend' })}>${orgArg.status === 'suspended' ? 'Unsuspend' : 'Suspend'}</button>`,
|
|
@@ -2327,21 +2511,17 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2327
2511
|
badge=${`${this.orgs.length} total`}
|
|
2328
2512
|
empty-title="No organisations"
|
|
2329
2513
|
empty-description="No organisations are visible to this admin session."
|
|
2330
|
-
.columns=${
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
{ label: 'Slug', mono: true, hideBelow: 'mobile' },
|
|
2342
|
-
{ label: 'Role' },
|
|
2343
|
-
{ label: 'Identifier', mono: true, hideBelow: 'tablet' },
|
|
2344
|
-
]}
|
|
2514
|
+
.columns=${[
|
|
2515
|
+
{ label: 'Organisation' },
|
|
2516
|
+
{ label: 'Slug', mono: true, hideBelow: 'mobile' },
|
|
2517
|
+
...(hasMemberCounts ? [{ label: 'Members', mono: true, hideBelow: 'mobile' }] : []),
|
|
2518
|
+
...(hasAdminFields
|
|
2519
|
+
? [{ label: 'Plan' }, { label: 'Status' }, { label: '' }]
|
|
2520
|
+
: [
|
|
2521
|
+
{ label: 'Role' },
|
|
2522
|
+
{ label: 'Identifier', mono: true, hideBelow: 'tablet' },
|
|
2523
|
+
]),
|
|
2524
|
+
]}
|
|
2345
2525
|
.rows=${orgRows}
|
|
2346
2526
|
></idp-data-table>
|
|
2347
2527
|
</div>
|
|
@@ -2409,6 +2589,7 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2409
2589
|
'org-settings': () => this.renderOrgSettings(),
|
|
2410
2590
|
'org-members': () => this.renderOrgMembers(),
|
|
2411
2591
|
'org-apps': () => this.renderOrgApps(),
|
|
2592
|
+
'org-sso': () => this.renderOrgSso(),
|
|
2412
2593
|
support: () => this.renderSupport(),
|
|
2413
2594
|
'ga-users': () => this.renderGAUsers(),
|
|
2414
2595
|
'ga-orgs': () => this.renderGAOrgs(),
|
|
@@ -2417,15 +2598,27 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2417
2598
|
return (renderers[this.page] || renderers.overview)();
|
|
2418
2599
|
}
|
|
2419
2600
|
|
|
2601
|
+
private handleMobileNavKeydown(eventArg: KeyboardEvent) {
|
|
2602
|
+
if (eventArg.key === 'Escape') {
|
|
2603
|
+
this.mobileNavOpen = false;
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2420
2607
|
public render(): TemplateResult {
|
|
2421
2608
|
return html`
|
|
2422
2609
|
<div
|
|
2423
2610
|
class="shell"
|
|
2424
|
-
@idp-admin-navigate=${this.handleSidebarNavigate}
|
|
2611
|
+
@idp-admin-navigate=${(eventArg: CustomEvent) => { this.mobileNavOpen = false; this.handleSidebarNavigate(eventArg as CustomEvent<IIdpAdminNavigateEventDetail>); }}
|
|
2425
2612
|
@idp-admin-org-select=${this.handleSidebarOrgSelect}
|
|
2426
2613
|
@idp-admin-org-create-request=${this.requestOrgCreate}
|
|
2427
2614
|
@idp-admin-logout-request=${this.requestLogout}
|
|
2428
2615
|
>
|
|
2616
|
+
<div class="mobile-topbar">
|
|
2617
|
+
<button class="mobile-nav-toggle" aria-label="Open navigation" aria-haspopup="dialog" aria-expanded=${this.mobileNavOpen} @click=${() => { this.mobileNavOpen = true; }}>
|
|
2618
|
+
<idp-icon name="lucide:Menu" size="17"></idp-icon>
|
|
2619
|
+
</button>
|
|
2620
|
+
<span class="mobile-topbar-title">idp.global</span>
|
|
2621
|
+
</div>
|
|
2429
2622
|
<idp-admin-sidebar
|
|
2430
2623
|
.page=${this.page}
|
|
2431
2624
|
.user=${this.user}
|
|
@@ -2435,12 +2628,31 @@ export class IdpAdminShell extends DeesElement {
|
|
|
2435
2628
|
.globalAdmin=${this.globalAdmin}
|
|
2436
2629
|
.sessionCount=${this.sessions.length}
|
|
2437
2630
|
></idp-admin-sidebar>
|
|
2631
|
+
${this.mobileNavOpen
|
|
2632
|
+
? html`
|
|
2633
|
+
<div class="mobile-drawer-backdrop" @click=${() => { this.mobileNavOpen = false; }}></div>
|
|
2634
|
+
<div class="mobile-drawer" role="dialog" aria-label="Navigation" @keydown=${this.handleMobileNavKeydown}>
|
|
2635
|
+
<button class="mobile-drawer-close" aria-label="Close navigation" @click=${() => { this.mobileNavOpen = false; }}>
|
|
2636
|
+
<idp-icon name="x" size="16"></idp-icon>
|
|
2637
|
+
</button>
|
|
2638
|
+
<idp-admin-sidebar
|
|
2639
|
+
.page=${this.page}
|
|
2640
|
+
.user=${this.user}
|
|
2641
|
+
.accounts=${this.accounts}
|
|
2642
|
+
.orgs=${this.orgs}
|
|
2643
|
+
.selectedOrgId=${this.selectedOrgId}
|
|
2644
|
+
.globalAdmin=${this.globalAdmin}
|
|
2645
|
+
.sessionCount=${this.sessions.length}
|
|
2646
|
+
></idp-admin-sidebar>
|
|
2647
|
+
</div>
|
|
2648
|
+
`
|
|
2649
|
+
: html``}
|
|
2438
2650
|
<main>${this.renderMainContent()}</main>
|
|
2439
2651
|
</div>
|
|
2440
2652
|
${this.renderDialog()}
|
|
2441
2653
|
${this.toast
|
|
2442
2654
|
? html`
|
|
2443
|
-
<div class="toast ${this.toast.tone}">
|
|
2655
|
+
<div class="toast ${this.toast.tone}" role="status" aria-live="polite">
|
|
2444
2656
|
<idp-icon name=${this.toast.tone === 'ok' ? 'check' : 'alert'} size="14"></idp-icon>
|
|
2445
2657
|
<span style="flex:1">${this.toast.message}</span>
|
|
2446
2658
|
</div>
|
|
@@ -444,6 +444,7 @@ export class IdpAdminSidebar extends DeesElement {
|
|
|
444
444
|
{ id: 'org-settings', label: 'Settings', icon: 'settings' },
|
|
445
445
|
{ id: 'org-members', label: 'Members', icon: 'users' },
|
|
446
446
|
{ id: 'org-apps', label: 'OAuth Apps', icon: 'box' },
|
|
447
|
+
{ id: 'org-sso', label: 'SSO & Provisioning', icon: 'key' },
|
|
447
448
|
];
|
|
448
449
|
|
|
449
450
|
private supportNav: TNavItem[] = [
|
|
@@ -534,7 +535,7 @@ export class IdpAdminSidebar extends DeesElement {
|
|
|
534
535
|
return html`
|
|
535
536
|
<div class="nav-list">
|
|
536
537
|
${items.map((item) => html`
|
|
537
|
-
<button class="nav-item ${item.id === active ? 'active' : ''}" @click=${() => this.setPage(item.id)}>
|
|
538
|
+
<button class="nav-item ${item.id === active ? 'active' : ''}" aria-current=${item.id === active ? 'page' : 'false'} @click=${() => this.setPage(item.id)}>
|
|
538
539
|
<idp-icon name=${item.icon as any} size="14"></idp-icon>
|
|
539
540
|
${item.label}
|
|
540
541
|
${item.badge ? html`<idp-badge variant="accent" style="margin-left:auto">${item.badge}</idp-badge>` : html``}
|
|
@@ -603,13 +604,13 @@ export class IdpAdminSidebar extends DeesElement {
|
|
|
603
604
|
<span class="logo-text">idp.global</span>
|
|
604
605
|
</div>
|
|
605
606
|
</div>
|
|
606
|
-
<
|
|
607
|
+
<nav class="nav-wrap" aria-label="Console navigation">
|
|
607
608
|
<div class="nav-section"><div class="nav-title">Workspace</div>${this.renderNavGroup(this.workspaceNav, this.page)}</div>
|
|
608
609
|
<div class="nav-section"><div class="nav-title">My Account</div>${this.renderNavGroup(this.accountNav, this.page)}</div>
|
|
609
610
|
<div class="nav-section">
|
|
610
611
|
<div class="nav-title">Organisation</div>
|
|
611
612
|
<div class="org-switch-wrap">
|
|
612
|
-
<button class="org-switch ${this.orgMenuOpen ? 'open' : ''}" @click=${() => { this.orgMenuOpen = !this.orgMenuOpen; }}>
|
|
613
|
+
<button class="org-switch ${this.orgMenuOpen ? 'open' : ''}" aria-haspopup="menu" aria-expanded=${this.orgMenuOpen} @click=${() => { this.orgMenuOpen = !this.orgMenuOpen; }}>
|
|
613
614
|
<span class="org-avatar">${currentOrg.name.slice(0, 2).toUpperCase()}</span>
|
|
614
615
|
<span class="org-name">${currentOrg.name}</span>
|
|
615
616
|
<idp-icon name="chevron-down" size="10"></idp-icon>
|
|
@@ -633,7 +634,7 @@ export class IdpAdminSidebar extends DeesElement {
|
|
|
633
634
|
</div>
|
|
634
635
|
<div class="nav-section"><div class="nav-title">Support</div>${this.renderNavGroup(this.supportNav, this.page)}</div>
|
|
635
636
|
${this.globalAdmin ? html`<div class="nav-section"><div class="nav-title">Global Admin</div>${this.renderNavGroup(this.adminNav, this.page)}</div>` : html``}
|
|
636
|
-
</
|
|
637
|
+
</nav>
|
|
637
638
|
<div class="user-footer">
|
|
638
639
|
<button class="user-trigger ${this.userMenuOpen ? 'open' : ''}" aria-haspopup="menu" aria-expanded=${this.userMenuOpen} @click=${() => { this.userMenuOpen = !this.userMenuOpen; }}>
|
|
639
640
|
<span class="user-avatar">${this.userInitials}</span>
|