@ibgib/web-gib 0.0.52 → 0.0.55
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 +7 -0
- package/dist/AUTO-GENERATED-version.d.mts +1 -1
- package/dist/AUTO-GENERATED-version.mjs +1 -1
- package/dist/api/commands/chat/hello-world.mjs.map +1 -1
- package/dist/api/commands/command-constants.d.mts +4 -4
- package/dist/api/commands/command-constants.d.mts.map +1 -1
- package/dist/api/commands/command-service-v1.d.mts.map +1 -1
- package/dist/api/commands/command-service-v1.mjs.map +1 -1
- package/dist/api/commands/ibgib/get-ibgibs.d.mts.map +1 -1
- package/dist/api/commands/ibgib/get-ibgibs.mjs.map +1 -1
- package/dist/api/ibgib-api-bridge.d.mts +81 -0
- package/dist/api/ibgib-api-bridge.d.mts.map +1 -0
- package/dist/api/ibgib-api-bridge.mjs +259 -0
- package/dist/api/ibgib-api-bridge.mjs.map +1 -0
- package/dist/app-bootstrap/init-orchestration.d.mts +1 -1
- package/dist/app-bootstrap/init-orchestration.d.mts.map +1 -1
- package/dist/app-bootstrap/init-orchestration.mjs +17 -3
- package/dist/app-bootstrap/init-orchestration.mjs.map +1 -1
- package/dist/assets/fullscreen-dialog.html +18 -0
- package/dist/assumptions.respec.mjs.map +1 -1
- package/dist/common/settings/settings-constants.d.mts.map +1 -1
- package/dist/helpers.d.mts.map +1 -1
- package/dist/helpers.mjs.map +1 -1
- package/dist/helpers.web.d.mts.map +1 -1
- package/dist/helpers.web.mjs.map +1 -1
- package/dist/helpers.web.respec.mjs.map +1 -1
- package/dist/identity/keystone-sync-service.d.mts +37 -0
- package/dist/identity/keystone-sync-service.d.mts.map +1 -0
- package/dist/identity/keystone-sync-service.mjs +211 -0
- package/dist/identity/keystone-sync-service.mjs.map +1 -0
- package/dist/identity/sso/sso-custodian-service.d.mts.map +1 -1
- package/dist/identity/sso/sso-custodian-service.mjs.map +1 -1
- package/dist/identity/sso/sso-custodian-service.respec.mjs.map +1 -1
- package/dist/index.d.mts +17 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +21 -26
- package/dist/index.mjs.map +1 -1
- package/dist/storage/storage-helpers.web.mjs.map +1 -1
- package/dist/ui/component/common-component-styles.css +270 -0
- package/dist/ui/component/ibgib-component-service.d.mts.map +1 -1
- package/dist/ui/component/ibgib-dynamic-component-bases.d.mts.map +1 -1
- package/dist/ui/component/ibgib-dynamic-component-bases.mjs.map +1 -1
- package/dist/ui/component/identity/add-device/add-device.css +133 -0
- package/dist/ui/component/identity/add-device/add-device.d.mts +49 -0
- package/dist/ui/component/identity/add-device/add-device.d.mts.map +1 -0
- package/dist/ui/component/identity/add-device/add-device.html +52 -0
- package/dist/ui/component/identity/add-device/add-device.mjs +321 -0
- package/dist/ui/component/identity/add-device/add-device.mjs.map +1 -0
- package/dist/ui/component/identity/identity-header/identity-header.css +317 -0
- package/dist/ui/component/identity/identity-header/identity-header.d.mts +85 -0
- package/dist/ui/component/identity/identity-header/identity-header.d.mts.map +1 -0
- package/dist/ui/component/identity/identity-header/identity-header.html +72 -0
- package/dist/ui/component/identity/identity-header/identity-header.mjs +546 -0
- package/dist/ui/component/identity/identity-header/identity-header.mjs.map +1 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.css +178 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.d.mts +76 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.d.mts.map +1 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.html +19 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.mjs +591 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.mjs.map +1 -0
- package/dist/ui/component/identity/index.d.mts +17 -0
- package/dist/ui/component/identity/index.d.mts.map +1 -0
- package/dist/ui/component/identity/index.mjs +34 -0
- package/dist/ui/component/identity/index.mjs.map +1 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.css +97 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts +58 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts.map +1 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.html +51 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs +410 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs.map +1 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.css +621 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.d.mts +98 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.d.mts.map +1 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.html +154 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.mjs +1377 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.mjs.map +1 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.css +46 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.d.mts +64 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.d.mts.map +1 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.html +15 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.mjs +300 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.mjs.map +1 -0
- package/dist/ui/component/identity/remove-device/remove-device.css +118 -0
- package/dist/ui/component/identity/remove-device/remove-device.d.mts +50 -0
- package/dist/ui/component/identity/remove-device/remove-device.d.mts.map +1 -0
- package/dist/ui/component/identity/remove-device/remove-device.html +31 -0
- package/dist/ui/component/identity/remove-device/remove-device.mjs +188 -0
- package/dist/ui/component/identity/remove-device/remove-device.mjs.map +1 -0
- package/dist/ui/ui-constants.d.mts +1 -0
- package/dist/ui/ui-constants.d.mts.map +1 -1
- package/dist/ui/ui-constants.mjs +1 -0
- package/dist/ui/ui-constants.mjs.map +1 -1
- package/dist/ui/ui-types.d.mts +7 -0
- package/dist/ui/ui-types.d.mts.map +1 -1
- package/dist/witness/agent/agent-constants.d.mts.map +1 -1
- package/dist/witness/agent/agent-helpers.mjs.map +1 -1
- package/dist/witness/agent/agent-one-file.d.mts.map +1 -1
- package/dist/witness/agent/agent-one-file.mjs.map +1 -1
- package/dist/witness/agent/agents-service-v1.d.mts.map +1 -1
- package/dist/witness/agent/agents-service-v1.mjs.map +1 -1
- package/dist/witness/agent/gemini/agent-witness-gemini-v1.d.mts.map +1 -1
- package/dist/witness/agent/gemini/gemini-agent-factory.d.mts.map +1 -1
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.d.mts.map +1 -1
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts +4 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts.map +1 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs +40 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs.map +1 -1
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.d.mts.map +1 -1
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.d.mts.map +1 -1
- package/package.json +2 -2
- package/src/AUTO-GENERATED-version.mts +1 -1
- package/src/api/ibgib-api-bridge.mts +292 -0
- package/src/app-bootstrap/init-orchestration.mts +17 -6
- package/src/custom.d.ts +11 -0
- package/src/identity/keystone-sync-service.mts +257 -0
- package/src/index.mts +24 -25
- package/src/ui/component/README.md +82 -5
- package/src/ui/component/common-component-styles.css +270 -0
- package/src/ui/component/identity/add-device/add-device.css +133 -0
- package/src/ui/component/identity/add-device/add-device.html +52 -0
- package/src/ui/component/identity/add-device/add-device.mts +397 -0
- package/src/ui/component/identity/identity-header/IMPLEMENTATION.md +45 -0
- package/src/ui/component/identity/identity-header/identity-header.css +317 -0
- package/src/ui/component/identity/identity-header/identity-header.html +72 -0
- package/src/ui/component/identity/identity-header/identity-header.mts +651 -0
- package/src/ui/component/identity/identity-manager/IMPLEMENTATION.md +100 -0
- package/src/ui/component/identity/identity-manager/identity-manager.css +178 -0
- package/src/ui/component/identity/identity-manager/identity-manager.html +19 -0
- package/src/ui/component/identity/identity-manager/identity-manager.mts +675 -0
- package/src/ui/component/identity/index.mts +36 -0
- package/src/ui/component/identity/keystone-creator/keystone-creator.css +97 -0
- package/src/ui/component/identity/keystone-creator/keystone-creator.html +51 -0
- package/src/ui/component/identity/keystone-creator/keystone-creator.mts +497 -0
- package/src/ui/component/identity/keystone-details/keystone-details.css +621 -0
- package/src/ui/component/identity/keystone-details/keystone-details.html +154 -0
- package/src/ui/component/identity/keystone-details/keystone-details.mts +1506 -0
- package/src/ui/component/identity/keystone-scrubber/SCRUBBER_IMPLEMENTATION.md +33 -0
- package/src/ui/component/identity/keystone-scrubber/keystone-scrubber.css +46 -0
- package/src/ui/component/identity/keystone-scrubber/keystone-scrubber.html +15 -0
- package/src/ui/component/identity/keystone-scrubber/keystone-scrubber.mts +355 -0
- package/src/ui/component/identity/remove-device/remove-device.css +118 -0
- package/src/ui/component/identity/remove-device/remove-device.html +31 -0
- package/src/ui/component/identity/remove-device/remove-device.mts +247 -0
- package/src/ui/ui-constants.mts +1 -0
- package/src/ui/ui-types.mts +8 -0
- package/src/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mts +42 -1
- package/tools/auto-generated-agent-skills/skills/ibgib-dependency-graph/SKILL.md +209 -0
- package/tools/auto-generated-agent-skills/skills/ibgib-implementation-plan/SKILL.md +102 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
import thisCss from "./identity-manager.css";
|
|
2
|
+
import thisHtml from "./identity-manager.html";
|
|
3
|
+
import commonComponentStylesCss from "../../common-component-styles.css";
|
|
4
|
+
|
|
5
|
+
import { delay, extractErrorMsg, pretty } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
6
|
+
import { IbGibAddr } from "@ibgib/ts-gib/dist/types.mjs";
|
|
7
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
8
|
+
import { getIbAndGib, getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
9
|
+
import { ROOT_ADDR } from "@ibgib/ts-gib/dist/V1/constants.mjs";
|
|
10
|
+
import { getGibInfo } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
|
|
11
|
+
import { KeystoneService_V1 } from "@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs";
|
|
12
|
+
import { getTjpAddr } from "@ibgib/core-gib/dist/common/other/ibgib-helper.mjs";
|
|
13
|
+
import { mut8Timeline } from "@ibgib/core-gib/dist/timeline/timeline-api.mjs";
|
|
14
|
+
import { MetaspaceService } from "@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs";
|
|
15
|
+
import {
|
|
16
|
+
IbGibDynamicComponentMetaBase,
|
|
17
|
+
IbGibDynamicComponentInstanceBase_ParentOfTabs,
|
|
18
|
+
} from "../../ibgib-dynamic-component-bases.mjs";
|
|
19
|
+
import {
|
|
20
|
+
ElementsBase, ChildInfoBase, IbGibDynamicComponentInstance,
|
|
21
|
+
IbGibDynamicComponentInstanceInitOpts,
|
|
22
|
+
} from "../../component-types.mjs";
|
|
23
|
+
import { getDeterministicColorInfo, getGlobalMetaspace_waitIfNeeded } from "../../../../helpers.mjs";
|
|
24
|
+
import { SettingsType } from "../../../../common/settings/settings-constants.mjs";
|
|
25
|
+
import { Settings_General, Settings_IdentityManager } from "../../../../common/settings/settings-types.mjs";
|
|
26
|
+
import { getSectionName } from "../../../../common/settings/settings-helpers.mjs";
|
|
27
|
+
import { getComponentSvc } from "../../ibgib-component-service.mjs";
|
|
28
|
+
import { EVENT_IBGIB_IDENTITY_REQUEST_CHANGE, EVENT_IBGIB_IDENTITY_CHANGED, EVENT_IBGIB_UI_MESSAGE } from "../../../ui-constants.mjs";
|
|
29
|
+
import { getComponentCtorArg } from "../../../../app-bootstrap/init-orchestration.mjs";
|
|
30
|
+
import { KEYSTONE_ATOM } from "@ibgib/core-gib/dist/keystone/keystone-constants.mjs";
|
|
31
|
+
|
|
32
|
+
export const IDENTITY_MANAGER_COMPONENT_NAME = 'ibgib-identity-manager';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Metadata for the Identity Manager component.
|
|
36
|
+
*/
|
|
37
|
+
export class IdentityManagerComponentMeta extends IbGibDynamicComponentMetaBase {
|
|
38
|
+
protected lc: string = `[IdentityManagerComponentMeta]`;
|
|
39
|
+
|
|
40
|
+
routeRegExp?: RegExp = new RegExp(`^${IDENTITY_MANAGER_COMPONENT_NAME}$`);
|
|
41
|
+
componentName = IDENTITY_MANAGER_COMPONENT_NAME;
|
|
42
|
+
|
|
43
|
+
constructor() {
|
|
44
|
+
super(getComponentCtorArg());
|
|
45
|
+
if (!customElements.get(this.componentName)) {
|
|
46
|
+
customElements.define(this.componentName, IdentityManagerComponentInstance);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async createInstance({
|
|
51
|
+
path,
|
|
52
|
+
ibGibAddr
|
|
53
|
+
}: {
|
|
54
|
+
path: string;
|
|
55
|
+
ibGibAddr: IbGibAddr;
|
|
56
|
+
}): Promise<IbGibDynamicComponentInstance> {
|
|
57
|
+
const lc = `${this.lc}[${this.createInstance.name}]`;
|
|
58
|
+
const component = document.createElement(this.componentName) as IdentityManagerComponentInstance;
|
|
59
|
+
await component.initialize({
|
|
60
|
+
ibGibAddr,
|
|
61
|
+
meta: this,
|
|
62
|
+
html: thisHtml,
|
|
63
|
+
css: [commonComponentStylesCss, thisCss],
|
|
64
|
+
});
|
|
65
|
+
return component;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface IdentityTabInfo extends ChildInfoBase<IbGibDynamicComponentInstance<any, any>> {
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* References to DOM elements within the component's shadow root.
|
|
74
|
+
*/
|
|
75
|
+
interface IdentityManagerElements extends ElementsBase {
|
|
76
|
+
containerEl: HTMLDivElement;
|
|
77
|
+
titleEl: HTMLHeadingElement;
|
|
78
|
+
tabsListEl: HTMLDivElement;
|
|
79
|
+
btnAddIdentityEl: HTMLButtonElement;
|
|
80
|
+
noIdentityPlaceholderEl: HTMLDivElement;
|
|
81
|
+
btnCreatePlaceholderEl: HTMLButtonElement;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Concrete implementation of the Identity Manager component.
|
|
86
|
+
*/
|
|
87
|
+
export class IdentityManagerComponentInstance
|
|
88
|
+
extends IbGibDynamicComponentInstanceBase_ParentOfTabs<Settings_IdentityManager, IbGib_V1, IdentityManagerElements, IdentityTabInfo>
|
|
89
|
+
implements IbGibDynamicComponentInstance<IbGib_V1, IdentityManagerElements> {
|
|
90
|
+
|
|
91
|
+
protected override lc: string = `[IdentityManagerComponentInstance]`;
|
|
92
|
+
|
|
93
|
+
private globalActiveAddr: string | null = null;
|
|
94
|
+
private _onIdentityChanged: ((e: any) => void) | null = null;
|
|
95
|
+
private _onUiMessage: ((e: any) => void) | null = null;
|
|
96
|
+
private keystoneCache: Map<string, { username: string, description: string, isPrimary: boolean, n: number }> = new Map();
|
|
97
|
+
metaspace: MetaspaceService | undefined;
|
|
98
|
+
|
|
99
|
+
protected get settingsType(): SettingsType {
|
|
100
|
+
return SettingsType.identityManager;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
constructor() {
|
|
104
|
+
super();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private async getKeystoneDetails(addr: string): Promise<{ username: string, description: string, isPrimary: boolean, n: number }> {
|
|
108
|
+
const cached = this.keystoneCache.get(addr);
|
|
109
|
+
if (cached) return cached;
|
|
110
|
+
|
|
111
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
112
|
+
if (!metaspace) return { username: '', description: '', isPrimary: false, n: 0 };
|
|
113
|
+
const space = await metaspace.getLocalUserSpace({ lock: false });
|
|
114
|
+
if (!space) return { username: '', description: '', isPrimary: false, n: 0 };
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const keystoneSvc = new KeystoneService_V1();
|
|
118
|
+
const info = await keystoneSvc.getKeystoneCommonInfo({
|
|
119
|
+
addr,
|
|
120
|
+
metaspace,
|
|
121
|
+
space
|
|
122
|
+
});
|
|
123
|
+
if (info) {
|
|
124
|
+
const details = {
|
|
125
|
+
username: info.name,
|
|
126
|
+
description: info.description,
|
|
127
|
+
isPrimary: info.isPrimary,
|
|
128
|
+
n: info.n
|
|
129
|
+
};
|
|
130
|
+
this.keystoneCache.set(addr, details);
|
|
131
|
+
return details;
|
|
132
|
+
}
|
|
133
|
+
} catch (err) {
|
|
134
|
+
console.warn(`Error getting details for keystone ${addr}: ${extractErrorMsg(err)}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { username: '', description: '', isPrimary: false, n: 0 };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
override async initialize(opts: IbGibDynamicComponentInstanceInitOpts): Promise<void> {
|
|
141
|
+
if (!this.metaspace) {
|
|
142
|
+
this.metaspace = await getGlobalMetaspace_waitIfNeeded({ delayIntervalMs: 50 });
|
|
143
|
+
}
|
|
144
|
+
opts.ibGibAddr = await this.metaspace.getLatestAddr({ addr: opts.ibGibAddr }) ?? opts.ibGibAddr;
|
|
145
|
+
await super.initialize(opts);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
override async created(): Promise<void> {
|
|
149
|
+
this.elements = {} as IdentityManagerElements;
|
|
150
|
+
|
|
151
|
+
const shadow = this.shadowRoot!;
|
|
152
|
+
this.elements.containerEl = shadow.getElementById('container') as HTMLDivElement;
|
|
153
|
+
this.elements.titleEl = shadow.getElementById('title') as HTMLHeadingElement;
|
|
154
|
+
this.elements.tabsListEl = shadow.getElementById('identity-tabs') as HTMLDivElement;
|
|
155
|
+
this.elements.btnAddIdentityEl = shadow.getElementById('btn-add-identity') as HTMLButtonElement;
|
|
156
|
+
this.elements.noIdentityPlaceholderEl = shadow.getElementById('no-identity-placeholder') as HTMLDivElement;
|
|
157
|
+
this.elements.btnCreatePlaceholderEl = shadow.getElementById('btn-create-placeholder') as HTMLButtonElement;
|
|
158
|
+
|
|
159
|
+
// ElementBase requires contentEl
|
|
160
|
+
this.elements.contentEl = shadow.getElementById('identity-manager-content') as HTMLDivElement;
|
|
161
|
+
|
|
162
|
+
this.initHandlers();
|
|
163
|
+
|
|
164
|
+
// Subscribe to global active identity changes
|
|
165
|
+
this._onIdentityChanged = async (e: any) => {
|
|
166
|
+
this.globalActiveAddr = e.detail?.activeIdentityAddr || null;
|
|
167
|
+
this.keystoneCache.clear();
|
|
168
|
+
await this.loadKeystonesIndex();
|
|
169
|
+
if (this.childInfos) {
|
|
170
|
+
for (const childInfo of this.childInfos) {
|
|
171
|
+
if (childInfo.component) {
|
|
172
|
+
try {
|
|
173
|
+
const comp = childInfo.component as any;
|
|
174
|
+
if (typeof comp.loadIbGib === 'function') {
|
|
175
|
+
await comp.loadIbGib({ getLatest: true });
|
|
176
|
+
}
|
|
177
|
+
} catch (err) {
|
|
178
|
+
console.warn(`[IdentityManager] Error reloading child component: ${extractErrorMsg(err)}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
await this.renderUI();
|
|
184
|
+
};
|
|
185
|
+
window.addEventListener(EVENT_IBGIB_IDENTITY_CHANGED, this._onIdentityChanged);
|
|
186
|
+
|
|
187
|
+
// Listen for requests to view details of a delegate (from child details component)
|
|
188
|
+
this.addEventListener('ibgib-view-keystone-details', async (e: any) => {
|
|
189
|
+
const addr = e.detail?.addr;
|
|
190
|
+
if (addr) {
|
|
191
|
+
await this.activateIbGib({ addr });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Listen for requests to switch to keystone-creator or add-device
|
|
196
|
+
if (this._onUiMessage) {
|
|
197
|
+
window.removeEventListener(EVENT_IBGIB_UI_MESSAGE, this._onUiMessage);
|
|
198
|
+
}
|
|
199
|
+
this._onUiMessage = (e: any) => {
|
|
200
|
+
const action = e.detail?.action;
|
|
201
|
+
const subAction = e.detail?.subAction;
|
|
202
|
+
if (action === 'show-keystone-creator' || subAction === 'show-keystone-creator') {
|
|
203
|
+
this.handleAddNewIdentityFlow('ibgib-keystone-creator');
|
|
204
|
+
} else if (action === 'show-add-device' || subAction === 'show-add-device') {
|
|
205
|
+
this.handleAddNewIdentityFlow('ibgib-add-device');
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
window.addEventListener(EVENT_IBGIB_UI_MESSAGE, this._onUiMessage);
|
|
209
|
+
|
|
210
|
+
if (this.ibGibAddr === ROOT_ADDR || !this.ibGib) {
|
|
211
|
+
await this.loadKeystonesIndex();
|
|
212
|
+
} else {
|
|
213
|
+
await this.initSettings();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
await this.renderUI();
|
|
217
|
+
|
|
218
|
+
// Spin off tab restore or defaults to allow createdPromise to resolve first
|
|
219
|
+
this.restoreOrInitTabs();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private async restoreOrInitTabs(): Promise<void> {
|
|
223
|
+
const settings = await this.getSettings<Settings_IdentityManager>({
|
|
224
|
+
settingsType: this.settingsType,
|
|
225
|
+
useCase: 'current',
|
|
226
|
+
});
|
|
227
|
+
if (settings) {
|
|
228
|
+
const validAddrs = (settings.openChildTjpAddrs ?? []).filter(addr => {
|
|
229
|
+
if (!addr || addr === '^' || addr === 'gib') return false;
|
|
230
|
+
const { gib } = getIbAndGib({ ibGibAddr: addr });
|
|
231
|
+
return !!gib && gib !== 'gib' && gib !== '^';
|
|
232
|
+
});
|
|
233
|
+
if (validAddrs.length !== (settings.openChildTjpAddrs ?? []).length) {
|
|
234
|
+
settings.openChildTjpAddrs = validAddrs;
|
|
235
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
236
|
+
if (metaspace) {
|
|
237
|
+
const sectionName_current = await getSectionName({
|
|
238
|
+
settingsType: this.settingsType,
|
|
239
|
+
useCase: 'current',
|
|
240
|
+
});
|
|
241
|
+
await mut8Timeline({
|
|
242
|
+
timeline: this.settings!.ibGib!,
|
|
243
|
+
metaspace,
|
|
244
|
+
mut8Opts: {
|
|
245
|
+
dataToAddOrPatch: {
|
|
246
|
+
sections: {
|
|
247
|
+
[sectionName_current]: settings,
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (!settings || (settings.openChildTjpAddrs ?? []).length === 0) {
|
|
257
|
+
await this.loadDefaultPrimaryIdentityTabs();
|
|
258
|
+
} else {
|
|
259
|
+
await this.reopenOldTabs();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
override async disconnected(): Promise<void> {
|
|
264
|
+
if (this._onIdentityChanged) {
|
|
265
|
+
window.removeEventListener(EVENT_IBGIB_IDENTITY_CHANGED, this._onIdentityChanged);
|
|
266
|
+
this._onIdentityChanged = null;
|
|
267
|
+
}
|
|
268
|
+
if (this._onUiMessage) {
|
|
269
|
+
window.removeEventListener(EVENT_IBGIB_UI_MESSAGE, this._onUiMessage);
|
|
270
|
+
this._onUiMessage = null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private async loadKeystonesIndex(): Promise<void> {
|
|
275
|
+
const lc = `${this.lc}[loadKeystonesIndex]`;
|
|
276
|
+
try {
|
|
277
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
278
|
+
if (!metaspace) { return; }
|
|
279
|
+
const space = await metaspace.getLocalUserSpace({ lock: false });
|
|
280
|
+
if (!space) { return; }
|
|
281
|
+
const keystonesIndex = await metaspace.getSpecialIbGib({
|
|
282
|
+
type: "keystones",
|
|
283
|
+
space,
|
|
284
|
+
initialize: true,
|
|
285
|
+
});
|
|
286
|
+
if (keystonesIndex) {
|
|
287
|
+
this.ibGibAddr = getIbGibAddr({ ibGib: keystonesIndex });
|
|
288
|
+
await this.loadIbGib({ getLatest: true });
|
|
289
|
+
await this.initSettings();
|
|
290
|
+
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
private initHandlers() {
|
|
297
|
+
// Buttons
|
|
298
|
+
this.elements!.btnAddIdentityEl.addEventListener('click', () => this.handleAddNewIdentityFlow('ibgib-keystone-creator'));
|
|
299
|
+
this.elements!.btnCreatePlaceholderEl.addEventListener('click', () => this.handleAddNewIdentityFlow('ibgib-keystone-creator'));
|
|
300
|
+
|
|
301
|
+
// Convert vertical mouse wheel scrolling into horizontal scroll for tabs
|
|
302
|
+
this.elements!.tabsListEl.addEventListener('wheel', (e: WheelEvent) => {
|
|
303
|
+
if (e.deltaY !== 0) {
|
|
304
|
+
e.preventDefault();
|
|
305
|
+
this.elements!.tabsListEl.scrollBy({ left: e.deltaY, behavior: 'smooth' });
|
|
306
|
+
}
|
|
307
|
+
}, { passive: false });
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
protected async handleAddNewIdentityFlow(componentPath: 'ibgib-keystone-creator' | 'ibgib-add-device' = 'ibgib-keystone-creator') {
|
|
311
|
+
const lc = `${this.lc}[${this.handleAddNewIdentityFlow.name}]`;
|
|
312
|
+
console.log(`${lc} Triggering identity creation/import flow (${componentPath})...`);
|
|
313
|
+
try {
|
|
314
|
+
const componentSvc = await getComponentSvc();
|
|
315
|
+
const childComp = await componentSvc.getComponentInstance({
|
|
316
|
+
path: componentPath,
|
|
317
|
+
ibGibAddr: ROOT_ADDR,
|
|
318
|
+
useRegExpPrefilter: true,
|
|
319
|
+
});
|
|
320
|
+
if (childComp) {
|
|
321
|
+
// Hide placeholder
|
|
322
|
+
this.elements!.noIdentityPlaceholderEl.classList.add('hidden');
|
|
323
|
+
|
|
324
|
+
// Clear any previous creator/details/add-device
|
|
325
|
+
const existingCreator = this.elements!.contentEl.querySelector('ibgib-keystone-creator');
|
|
326
|
+
if (existingCreator) { existingCreator.remove(); }
|
|
327
|
+
const existingAddDevice = this.elements!.contentEl.querySelector('ibgib-add-device');
|
|
328
|
+
if (existingAddDevice) { existingAddDevice.remove(); }
|
|
329
|
+
|
|
330
|
+
// Clear active child component inside ParentOfTabs to prevent conflict
|
|
331
|
+
const active = this.activeChildInfo;
|
|
332
|
+
if (active) {
|
|
333
|
+
active.childBtnEl.classList.remove('active');
|
|
334
|
+
active.active = false;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
this.elements!.contentEl.innerHTML = '';
|
|
338
|
+
this.elements!.contentEl.appendChild(childComp as any);
|
|
339
|
+
console.log(`${lc} Mounted ${componentPath} successfully.`);
|
|
340
|
+
} else {
|
|
341
|
+
throw new Error(`Could not find meta for ${componentPath}`);
|
|
342
|
+
}
|
|
343
|
+
} catch (error) {
|
|
344
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
private async resolveActiveIdentity() {
|
|
349
|
+
const lc = `${this.lc}[resolveActiveIdentity]`;
|
|
350
|
+
try {
|
|
351
|
+
if (!this.settings) {
|
|
352
|
+
this.globalActiveAddr = null;
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const generalSettings = await this.getSettings<Settings_General>({
|
|
356
|
+
settingsType: SettingsType.general,
|
|
357
|
+
useCase: 'current',
|
|
358
|
+
});
|
|
359
|
+
const activeAddrInSettings = (generalSettings as any)?.activeIdentityAddr;
|
|
360
|
+
|
|
361
|
+
const registeredKeystones = this.ibGib?.rel8ns?.keystone ?? [];
|
|
362
|
+
const detailsPromises = registeredKeystones.map(async addr => {
|
|
363
|
+
const details = await this.getKeystoneDetails(addr);
|
|
364
|
+
return { addr, isPrimary: details?.isPrimary ?? false };
|
|
365
|
+
});
|
|
366
|
+
const resolvedDetails = await Promise.all(detailsPromises);
|
|
367
|
+
const primaryKeystones = resolvedDetails
|
|
368
|
+
.filter(item => item.isPrimary)
|
|
369
|
+
.map(item => item.addr);
|
|
370
|
+
|
|
371
|
+
if (activeAddrInSettings && primaryKeystones.includes(activeAddrInSettings)) {
|
|
372
|
+
this.globalActiveAddr = activeAddrInSettings;
|
|
373
|
+
} else if (primaryKeystones.length > 0) {
|
|
374
|
+
this.globalActiveAddr = primaryKeystones[0];
|
|
375
|
+
} else {
|
|
376
|
+
this.globalActiveAddr = null;
|
|
377
|
+
}
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
380
|
+
this.globalActiveAddr = null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
protected override async renderUI(): Promise<void> {
|
|
385
|
+
const lc = `${this.lc}[${this.renderUI.name}]`;
|
|
386
|
+
if (!this.elements) { return; }
|
|
387
|
+
|
|
388
|
+
await this.resolveActiveIdentity();
|
|
389
|
+
|
|
390
|
+
const keystones = this.ibGib?.rel8ns?.keystone ?? [];
|
|
391
|
+
if (keystones.length === 0 && this.childInfos.length === 0) {
|
|
392
|
+
this.elements.noIdentityPlaceholderEl.classList.remove('hidden');
|
|
393
|
+
this.elements.contentEl.innerHTML = '';
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
this.elements.noIdentityPlaceholderEl.classList.add('hidden');
|
|
398
|
+
|
|
399
|
+
// Render tab highlights
|
|
400
|
+
for (const info of this.childInfos) {
|
|
401
|
+
const btn = info.childBtnEl;
|
|
402
|
+
btn.className = `tab-btn ${info.active ? 'active' : ''} ${info.addr === this.globalActiveAddr ? 'global-active' : ''}`;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private async loadDefaultPrimaryIdentityTabs() {
|
|
407
|
+
const keystones = (this.ibGib?.rel8ns?.keystone ?? []).filter(addr => {
|
|
408
|
+
if (!addr || addr === '^' || addr === 'gib') return false;
|
|
409
|
+
const { gib } = getIbAndGib({ ibGibAddr: addr });
|
|
410
|
+
return !!gib && gib !== 'gib' && gib !== '^';
|
|
411
|
+
});
|
|
412
|
+
const detailsPromises = keystones.map(async addr => {
|
|
413
|
+
const details = await this.getKeystoneDetails(addr);
|
|
414
|
+
return { addr, isPrimary: details?.isPrimary ?? false };
|
|
415
|
+
});
|
|
416
|
+
const resolvedDetails = await Promise.all(detailsPromises);
|
|
417
|
+
const primaryKeystones = resolvedDetails
|
|
418
|
+
.filter(item => item.isPrimary)
|
|
419
|
+
.map(item => item.addr);
|
|
420
|
+
|
|
421
|
+
if (primaryKeystones.length === 0) {
|
|
422
|
+
this.elements!.noIdentityPlaceholderEl.classList.remove('hidden');
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
this.elements!.noIdentityPlaceholderEl.classList.add('hidden');
|
|
427
|
+
|
|
428
|
+
this.reloadingTabs = true;
|
|
429
|
+
try {
|
|
430
|
+
for (const addr of primaryKeystones) {
|
|
431
|
+
await this.activateIbGib({ addr });
|
|
432
|
+
}
|
|
433
|
+
} finally {
|
|
434
|
+
this.reloadingTabs = false;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Activate the global active identity (if open), or the first primary one
|
|
438
|
+
const activeToOpen = primaryKeystones.includes(this.globalActiveAddr || '')
|
|
439
|
+
? this.globalActiveAddr!
|
|
440
|
+
: primaryKeystones[0];
|
|
441
|
+
await this.activateIbGib({ addr: activeToOpen });
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
public override async activateIbGib({ addr, ibGib }: { addr?: IbGibAddr; ibGib?: IbGib_V1; }): Promise<void> {
|
|
445
|
+
const lc = `${this.lc}[activateIbGib]`;
|
|
446
|
+
try {
|
|
447
|
+
if (!this.metaspace) { throw new Error(`(UNEXPECTED) this.metaspace falsy? (E: f9e0e9a1427899eba8e469c18d7ae826)`); }
|
|
448
|
+
|
|
449
|
+
await super.activateIbGib({ addr, ibGib });
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
if (!this.activeChildInfo) { throw new Error(`(UNEXPECTED) activeChildInfo falsy after activateIbGib? (E: d76bd8bc300f3fdc486d50c8b2644826)`); }
|
|
453
|
+
|
|
454
|
+
ibGib ??= this.activeChildInfo.component?.ibGib;
|
|
455
|
+
|
|
456
|
+
if (!ibGib) { throw new Error(`(UNEXPECTED) ibGib falsy? (E: 5b6ec745dd32fd2128635728e3f35e26)`); }
|
|
457
|
+
|
|
458
|
+
if (!ibGib.ib.startsWith(KEYSTONE_ATOM)) {
|
|
459
|
+
throw new Error(`ibGib.ib (${ibGib.ib}) does not start with keystone atom (${KEYSTONE_ATOM}) (E: e0df410381c8e569eb6da996e79b6826)`);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
this.elements!.noIdentityPlaceholderEl.classList.add('hidden');
|
|
463
|
+
|
|
464
|
+
if (!this.reloadingTabs) {
|
|
465
|
+
const settings_current = await this.getSettings<Settings_IdentityManager>({
|
|
466
|
+
settingsType: this.settingsType,
|
|
467
|
+
useCase: 'current',
|
|
468
|
+
});
|
|
469
|
+
if (settings_current) {
|
|
470
|
+
let modified = false;
|
|
471
|
+
const tjpAddr = getTjpAddr({ ibGib: this.activeChildInfo.component?.ibGib || ibGib!, defaultIfNone: 'incomingAddr' });
|
|
472
|
+
if (tjpAddr) {
|
|
473
|
+
if (!settings_current.openChildTjpAddrs.includes(tjpAddr)) {
|
|
474
|
+
settings_current.openChildTjpAddrs.push(tjpAddr);
|
|
475
|
+
modified = true;
|
|
476
|
+
}
|
|
477
|
+
if (settings_current.activeChildTjpAddr !== tjpAddr) {
|
|
478
|
+
settings_current.activeChildTjpAddr = tjpAddr;
|
|
479
|
+
modified = true;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (modified) {
|
|
483
|
+
const metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
484
|
+
if (metaspace) {
|
|
485
|
+
const sectionName_current = await getSectionName({
|
|
486
|
+
settingsType: this.settingsType,
|
|
487
|
+
useCase: 'current',
|
|
488
|
+
});
|
|
489
|
+
await mut8Timeline({
|
|
490
|
+
timeline: this.settings!.ibGib!,
|
|
491
|
+
metaspace,
|
|
492
|
+
mut8Opts: {
|
|
493
|
+
dataToAddOrPatch: {
|
|
494
|
+
sections: {
|
|
495
|
+
[sectionName_current]: settings_current,
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
await this.renderUI();
|
|
506
|
+
} catch (error) {
|
|
507
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
protected async getLoadedChildInfo({
|
|
512
|
+
addr,
|
|
513
|
+
ibGib,
|
|
514
|
+
}: {
|
|
515
|
+
addr: IbGibAddr,
|
|
516
|
+
ibGib?: IbGib_V1,
|
|
517
|
+
}): Promise<IdentityTabInfo> {
|
|
518
|
+
const lc = `${this.lc}[getLoadedChildInfo]`;
|
|
519
|
+
try {
|
|
520
|
+
if (!addr) { throw new Error(`(UNEXPECTED) addr falsy?`); }
|
|
521
|
+
if (addr === '^' || addr === 'gib' || getIbAndGib({ ibGibAddr: addr }).gib === '^') {
|
|
522
|
+
throw new Error(`Cannot load child info for primitive address ${addr}`);
|
|
523
|
+
}
|
|
524
|
+
const tjpGib = getGibInfo({ ibGibAddr: addr }).tjpGib ?? getIbAndGib({ ibGibAddr: addr }).gib;
|
|
525
|
+
|
|
526
|
+
const fnCreateAndLoadChildComponent = async () => {
|
|
527
|
+
const componentSvc = await getComponentSvc();
|
|
528
|
+
const detailsComponent = await componentSvc.getComponentInstance({
|
|
529
|
+
path: 'ibgib-keystone-scrubber',
|
|
530
|
+
ibGibAddr: addr,
|
|
531
|
+
useRegExpPrefilter: true,
|
|
532
|
+
});
|
|
533
|
+
if (!detailsComponent) {
|
|
534
|
+
throw new Error(`(UNEXPECTED) detailsComponent falsy?`);
|
|
535
|
+
}
|
|
536
|
+
return detailsComponent;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
let tabInfo: IdentityTabInfo;
|
|
540
|
+
|
|
541
|
+
const filtered = this.childInfos.filter(x => {
|
|
542
|
+
const tabGibInfo = getGibInfo({ ibGibAddr: x.addr });
|
|
543
|
+
const tabTjpGib = tabGibInfo.tjpGib ?? getIbAndGib({ ibGibAddr: x.addr }).gib;
|
|
544
|
+
return tabTjpGib === tjpGib;
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
if (filtered.length > 0) {
|
|
548
|
+
if (filtered.length !== 1) { throw new Error(`(UNEXPECTED) filtered.length !== 1?`); }
|
|
549
|
+
tabInfo = filtered[0];
|
|
550
|
+
if (!tabInfo.component) {
|
|
551
|
+
tabInfo.component = await fnCreateAndLoadChildComponent();
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
const detailsComponent = await fnCreateAndLoadChildComponent();
|
|
555
|
+
let i = 0;
|
|
556
|
+
while (!detailsComponent.ibGib!) {
|
|
557
|
+
await delay(100);
|
|
558
|
+
i++;
|
|
559
|
+
if (i > 50) { // 5 seconds
|
|
560
|
+
debugger; // error loading details component ibgib
|
|
561
|
+
throw new Error(`(UNEXPECTED) detailsComponent.ibGib falsy? didn't load? (E: de50689834124914f770520f1eccb826)`);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
ibGib = detailsComponent.ibGib!;
|
|
565
|
+
addr = getIbGibAddr({ ibGib });
|
|
566
|
+
const tabBtnEl = await this.addChild({ addr, ibGib: ibGib! });
|
|
567
|
+
tabInfo = {
|
|
568
|
+
addr,
|
|
569
|
+
childBtnEl: tabBtnEl,
|
|
570
|
+
component: detailsComponent,
|
|
571
|
+
active: false,
|
|
572
|
+
};
|
|
573
|
+
this.childInfos.push(tabInfo);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return tabInfo;
|
|
577
|
+
} catch (error) {
|
|
578
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
579
|
+
throw error;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
protected override async addChild({
|
|
584
|
+
addr,
|
|
585
|
+
ibGib,
|
|
586
|
+
}: {
|
|
587
|
+
ibGib: IbGib_V1,
|
|
588
|
+
addr?: IbGibAddr,
|
|
589
|
+
}): Promise<HTMLElement> {
|
|
590
|
+
const lc = `${this.lc}[addChild]`;
|
|
591
|
+
try {
|
|
592
|
+
addr ??= getIbGibAddr({ ibGib });
|
|
593
|
+
if (addr === '^' || addr === 'gib' || getIbAndGib({ ibGibAddr: addr }).gib === '^') {
|
|
594
|
+
throw new Error(`Cannot add child tab for primitive address ${addr}`);
|
|
595
|
+
}
|
|
596
|
+
if (!this.elements) { throw new Error(`(UNEXPECTED) this.elements falsy?`); }
|
|
597
|
+
const { tabsListEl } = this.elements;
|
|
598
|
+
|
|
599
|
+
addr ??= getIbGibAddr({ ibGib });
|
|
600
|
+
|
|
601
|
+
const childBtnEl = document.createElement('button');
|
|
602
|
+
childBtnEl.className = 'tab-btn';
|
|
603
|
+
childBtnEl.id = `identity-tab-button-${addr}`;
|
|
604
|
+
|
|
605
|
+
await this.updateTabTitleAndText({ span: childBtnEl, ibGib, addr });
|
|
606
|
+
|
|
607
|
+
const details = await this.getKeystoneDetails(addr);
|
|
608
|
+
if (!details.isPrimary) {
|
|
609
|
+
const closeBtnEl = document.createElement('span');
|
|
610
|
+
closeBtnEl.className = 'close-tab-button';
|
|
611
|
+
closeBtnEl.textContent = ' ×';
|
|
612
|
+
closeBtnEl.style.marginLeft = '0.5rem';
|
|
613
|
+
closeBtnEl.style.cursor = 'pointer';
|
|
614
|
+
childBtnEl.appendChild(closeBtnEl);
|
|
615
|
+
closeBtnEl.addEventListener('click', async (event) => {
|
|
616
|
+
event.stopPropagation(); // Prevent activating the tab
|
|
617
|
+
await this.closeTab({ ibGib });
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
tabsListEl.appendChild(childBtnEl);
|
|
622
|
+
childBtnEl.addEventListener('click', async (event) => {
|
|
623
|
+
await this.activateIbGib({ addr });
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
return childBtnEl;
|
|
627
|
+
} catch (error) {
|
|
628
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
629
|
+
throw error;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
private async updateTabTitleAndText({
|
|
634
|
+
span,
|
|
635
|
+
ibGib,
|
|
636
|
+
addr,
|
|
637
|
+
}: {
|
|
638
|
+
span: HTMLElement,
|
|
639
|
+
ibGib: IbGib_V1,
|
|
640
|
+
addr: string,
|
|
641
|
+
}): Promise<void> {
|
|
642
|
+
const details = await this.getKeystoneDetails(addr);
|
|
643
|
+
let name = details.username;
|
|
644
|
+
const maxTabLen = 16;
|
|
645
|
+
if (name) {
|
|
646
|
+
if (name.length > maxTabLen) {
|
|
647
|
+
name = name.substring(0, maxTabLen - 3) + '...';
|
|
648
|
+
}
|
|
649
|
+
span.textContent = name;
|
|
650
|
+
} else {
|
|
651
|
+
let displayTab = addr;
|
|
652
|
+
if (displayTab.length > 12) {
|
|
653
|
+
displayTab = displayTab.substring(0, 5) + '...' + displayTab.substring(displayTab.length - 4);
|
|
654
|
+
}
|
|
655
|
+
span.textContent = displayTab;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
const tooltipParts: string[] = [];
|
|
659
|
+
if (details.username) {
|
|
660
|
+
tooltipParts.push(`User: ${details.username}`);
|
|
661
|
+
}
|
|
662
|
+
if (details.description) {
|
|
663
|
+
const desc = details.description.length > 100
|
|
664
|
+
? details.description.substring(0, 97) + '...'
|
|
665
|
+
: details.description;
|
|
666
|
+
tooltipParts.push(`Desc: ${desc}`);
|
|
667
|
+
}
|
|
668
|
+
tooltipParts.push(`Addr: ${addr}`);
|
|
669
|
+
span.title = tooltipParts.join('\n');
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
protected async removeTabBtn({ tabInfo }: { tabInfo: IdentityTabInfo }): Promise<void> {
|
|
673
|
+
this.elements!.tabsListEl.removeChild(tabInfo.childBtnEl);
|
|
674
|
+
}
|
|
675
|
+
}
|