@babylonjs/shared-ui-components 9.2.0 → 9.2.2
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/fluent/hoc/buttonLine.js +2 -1
- package/fluent/hoc/buttonLine.js.map +1 -1
- package/fluent/primitives/accordion.contexts.js +2 -2
- package/fluent/primitives/accordion.contexts.js.map +1 -1
- package/fluent/primitives/contextMenu.js.map +1 -1
- package/fluent/primitives/popover.js.map +1 -1
- package/fluent/primitives/tooltip.d.ts +1 -1
- package/fluent/primitives/tooltip.js.map +1 -1
- package/modularTool/components/errorBoundary.d.ts +31 -0
- package/modularTool/components/errorBoundary.js +91 -0
- package/modularTool/components/errorBoundary.js.map +1 -0
- package/modularTool/components/extensibleAccordion.d.ts +67 -0
- package/modularTool/components/extensibleAccordion.js +148 -0
- package/modularTool/components/extensibleAccordion.js.map +1 -0
- package/modularTool/components/pane.d.ts +4 -0
- package/modularTool/components/pane.js +20 -0
- package/modularTool/components/pane.js.map +1 -0
- package/modularTool/components/teachingMoment.d.ts +20 -0
- package/modularTool/components/teachingMoment.js +17 -0
- package/modularTool/components/teachingMoment.js.map +1 -0
- package/modularTool/components/theme.d.ts +10 -0
- package/modularTool/components/theme.js +24 -0
- package/modularTool/components/theme.js.map +1 -0
- package/modularTool/components/uxContextProvider.d.ts +2 -0
- package/modularTool/components/uxContextProvider.js +19 -0
- package/modularTool/components/uxContextProvider.js.map +1 -0
- package/modularTool/contexts/extensionManagerContext.d.ts +6 -0
- package/modularTool/contexts/extensionManagerContext.js +6 -0
- package/modularTool/contexts/extensionManagerContext.js.map +1 -0
- package/modularTool/contexts/settingsContext.d.ts +3 -0
- package/modularTool/contexts/settingsContext.js +6 -0
- package/modularTool/contexts/settingsContext.js.map +1 -0
- package/modularTool/extensibility/builtInsExtensionFeed.d.ts +21 -0
- package/modularTool/extensibility/builtInsExtensionFeed.js +26 -0
- package/modularTool/extensibility/builtInsExtensionFeed.js.map +1 -0
- package/modularTool/extensibility/extensionFeed.d.ts +113 -0
- package/modularTool/extensibility/extensionFeed.js +2 -0
- package/modularTool/extensibility/extensionFeed.js.map +1 -0
- package/modularTool/extensibility/extensionManager.d.ts +111 -0
- package/modularTool/extensibility/extensionManager.js +277 -0
- package/modularTool/extensibility/extensionManager.js.map +1 -0
- package/modularTool/hooks/observableHooks.d.ts +35 -0
- package/modularTool/hooks/observableHooks.js +84 -0
- package/modularTool/hooks/observableHooks.js.map +1 -0
- package/modularTool/hooks/resourceHooks.d.ts +20 -0
- package/modularTool/hooks/resourceHooks.js +101 -0
- package/modularTool/hooks/resourceHooks.js.map +1 -0
- package/modularTool/hooks/settingsHooks.d.ts +8 -0
- package/modularTool/hooks/settingsHooks.js +40 -0
- package/modularTool/hooks/settingsHooks.js.map +1 -0
- package/modularTool/hooks/teachingMomentHooks.d.ts +34 -0
- package/modularTool/hooks/teachingMomentHooks.js +89 -0
- package/modularTool/hooks/teachingMomentHooks.js.map +1 -0
- package/modularTool/hooks/themeHooks.d.ts +17 -0
- package/modularTool/hooks/themeHooks.js +38 -0
- package/modularTool/hooks/themeHooks.js.map +1 -0
- package/modularTool/hooks/useResizeHandle.d.ts +35 -0
- package/modularTool/hooks/useResizeHandle.js +75 -0
- package/modularTool/hooks/useResizeHandle.js.map +1 -0
- package/modularTool/misc/assert.d.ts +5 -0
- package/modularTool/misc/assert.js +10 -0
- package/modularTool/misc/assert.js.map +1 -0
- package/modularTool/misc/graphUtils.d.ts +44 -0
- package/modularTool/misc/graphUtils.js +90 -0
- package/modularTool/misc/graphUtils.js.map +1 -0
- package/modularTool/misc/observableCollection.d.ts +23 -0
- package/modularTool/misc/observableCollection.js +43 -0
- package/modularTool/misc/observableCollection.js.map +1 -0
- package/modularTool/modularTool.d.ts +42 -0
- package/modularTool/modularTool.js +244 -0
- package/modularTool/modularTool.js.map +1 -0
- package/modularTool/modularity/serviceContainer.d.ts +64 -0
- package/modularTool/modularity/serviceContainer.js +181 -0
- package/modularTool/modularity/serviceContainer.js.map +1 -0
- package/modularTool/modularity/serviceDefinition.d.ts +64 -0
- package/modularTool/modularity/serviceDefinition.js +11 -0
- package/modularTool/modularity/serviceDefinition.js.map +1 -0
- package/modularTool/services/extensionsListService.d.ts +3 -0
- package/modularTool/services/extensionsListService.js +202 -0
- package/modularTool/services/extensionsListService.js.map +1 -0
- package/modularTool/services/globalSettings.d.ts +3 -0
- package/modularTool/services/globalSettings.js +9 -0
- package/modularTool/services/globalSettings.js.map +1 -0
- package/modularTool/services/reactContextService.d.ts +18 -0
- package/modularTool/services/reactContextService.js +5 -0
- package/modularTool/services/reactContextService.js.map +1 -0
- package/modularTool/services/settingsService.d.ts +24 -0
- package/modularTool/services/settingsService.js +41 -0
- package/modularTool/services/settingsService.js.map +1 -0
- package/modularTool/services/settingsStore.d.ts +55 -0
- package/modularTool/services/settingsStore.js +35 -0
- package/modularTool/services/settingsStore.js.map +1 -0
- package/modularTool/services/shellService.d.ts +256 -0
- package/modularTool/services/shellService.js +729 -0
- package/modularTool/services/shellService.js.map +1 -0
- package/modularTool/services/shellSettingsService.d.ts +3 -0
- package/modularTool/services/shellSettingsService.js +35 -0
- package/modularTool/services/shellSettingsService.js.map +1 -0
- package/modularTool/services/themeSelectorService.d.ts +3 -0
- package/modularTool/services/themeSelectorService.js +42 -0
- package/modularTool/services/themeSelectorService.js.map +1 -0
- package/modularTool/services/themeService.d.ts +60 -0
- package/modularTool/services/themeService.js +69 -0
- package/modularTool/services/themeService.js.map +1 -0
- package/modularTool/services/toastService.d.ts +17 -0
- package/modularTool/services/toastService.js +5 -0
- package/modularTool/services/toastService.js.map +1 -0
- package/modularTool/themes/babylonTheme.d.ts +3 -0
- package/modularTool/themes/babylonTheme.js +36 -0
- package/modularTool/themes/babylonTheme.js.map +1 -0
- package/nodeGraphSystem/graphCanvas.js +2 -1
- package/nodeGraphSystem/graphCanvas.js.map +1 -1
- package/nodeGraphSystem/graphNode.d.ts +2 -0
- package/nodeGraphSystem/graphNode.js +5 -1
- package/nodeGraphSystem/graphNode.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceContainer.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/modularTool/modularity/serviceContainer.ts"],"names":[],"mappings":"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","sourcesContent":["import { type IDisposable } from \"core/index\";\r\n\r\nimport { type IService, type ServiceDefinition } from \"./serviceDefinition\";\r\n\r\nimport { SortGraph } from \"../misc/graphUtils\";\r\n\r\n// Service definitions should strongly typed when they are defined to avoid programming errors. However, they are tracked internally\r\n// in a weakly typed manner so they can be handled generically.\r\nexport type WeaklyTypedServiceDefinition = Omit<ServiceDefinition<IService<symbol>[] | [], IService<symbol>[] | []>, \"factory\"> & {\r\n /**\r\n * A factory function responsible for creating a service instance.\r\n */\r\n factory: (...args: any) => ReturnType<ServiceDefinition<IService<symbol>[] | [], IService<symbol>[] | []>[\"factory\"]>;\r\n};\r\n\r\n// This sorts a set of service definitions based on their dependencies (e.g. a topological sort).\r\nfunction SortServiceDefinitions(serviceDefinitions: WeaklyTypedServiceDefinition[]) {\r\n const sortedServiceDefinitions: typeof serviceDefinitions = [];\r\n SortGraph(\r\n serviceDefinitions,\r\n function* (serviceDefinition) {\r\n // Check each dependency.\r\n for (const contractIdentity of serviceDefinition.consumes ?? []) {\r\n // If another service definition produces the dependency contract, return it as an adjacent node for the purpose of sorting.\r\n yield* serviceDefinitions.filter((otherServiceDefinition) => (otherServiceDefinition.produces ?? []).includes(contractIdentity));\r\n }\r\n },\r\n sortedServiceDefinitions.push.bind(sortedServiceDefinitions)\r\n );\r\n return sortedServiceDefinitions;\r\n}\r\n\r\n/**\r\n * A service container manages the lifetimes of a set of services.\r\n * It takes care of instantiating the services in the correct order based on their dependencies,\r\n * passing dependencies through to services, and disposing of services when the container is disposed.\r\n */\r\nexport class ServiceContainer implements IDisposable {\r\n private _isDisposed = false;\r\n private readonly _serviceDefinitions = new Map<symbol, WeaklyTypedServiceDefinition>();\r\n private readonly _serviceDependents = new Map<WeaklyTypedServiceDefinition, Set<WeaklyTypedServiceDefinition>>();\r\n private readonly _serviceInstances = new Map<WeaklyTypedServiceDefinition, (IService<symbol> & Partial<IDisposable>) | void>();\r\n private readonly _children = new Set<ServiceContainer>();\r\n\r\n /**\r\n * Creates a new ServiceContainer.\r\n * @param _friendlyName A human-readable name for debugging.\r\n * @param _parent An optional parent container. Dependencies not found locally will be resolved from the parent.\r\n */\r\n public constructor(\r\n private readonly _friendlyName: string,\r\n private readonly _parent?: ServiceContainer\r\n ) {\r\n _parent?._children.add(this);\r\n }\r\n\r\n /**\r\n * Adds a set of service definitions in the service container.\r\n * The services are sorted based on their dependencies.\r\n * @param args The service definitions to register, and optionally an abort signal.\r\n * @returns A disposable that will remove the service definition from the service container.\r\n */\r\n public async addServicesAsync(\r\n ...args: WeaklyTypedServiceDefinition[] | [...serviceDefinitions: WeaklyTypedServiceDefinition[], abortSignal: AbortSignal]\r\n ): Promise<IDisposable> {\r\n if (this._isDisposed) {\r\n throw new Error(\"ServiceContainer is disposed.\");\r\n }\r\n\r\n const abortSignal = args[args.length - 1] instanceof AbortSignal ? (args.pop() as AbortSignal) : undefined;\r\n const serviceDefinitions = args as WeaklyTypedServiceDefinition[];\r\n\r\n const sortedServiceDefinitions = SortServiceDefinitions(serviceDefinitions);\r\n\r\n const dispose = () => {\r\n for (const serviceDefinition of sortedServiceDefinitions.reverse()) {\r\n this._removeService(serviceDefinition);\r\n }\r\n };\r\n\r\n try {\r\n for (const serviceDefinition of sortedServiceDefinitions) {\r\n // We could possibly optimize this by allowing some parallel initialization of services, but this would be way more complex, so let's wait and see if it's needed.\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._addServiceAsync(serviceDefinition, abortSignal);\r\n }\r\n } catch (error: unknown) {\r\n dispose();\r\n throw error;\r\n }\r\n\r\n return {\r\n dispose,\r\n };\r\n }\r\n\r\n /**\r\n * Registers a service definition in the service container.\r\n * @param serviceDefinition The service definition to register.\r\n * @param abortSignal An optional abort signal.\r\n * @returns A disposable that will remove the service definition from the service container.\r\n */\r\n public async addServiceAsync<Produces extends IService<symbol>[] = [], Consumes extends IService<symbol>[] = []>(\r\n serviceDefinition: ServiceDefinition<Produces, Consumes>,\r\n abortSignal?: AbortSignal\r\n ): Promise<IDisposable> {\r\n if (abortSignal) {\r\n return await this.addServicesAsync(serviceDefinition, abortSignal);\r\n } else {\r\n return await this.addServicesAsync(serviceDefinition);\r\n }\r\n }\r\n\r\n private async _addServiceAsync(service: WeaklyTypedServiceDefinition, abortSignal?: AbortSignal) {\r\n if (this._isDisposed) {\r\n throw new Error(`'${this._friendlyName}' container is disposed.`);\r\n }\r\n\r\n service.produces?.forEach((contract) => {\r\n if (this._serviceDefinitions.has(contract)) {\r\n throw new Error(`A service producing the contract '${contract.toString()}' has already been added to this '${this._friendlyName}' container.`);\r\n }\r\n });\r\n\r\n service.produces?.forEach((contract) => {\r\n this._serviceDefinitions.set(contract, service);\r\n });\r\n\r\n const dependencies = service.consumes?.map((contract) => this._resolveDependency(contract, service)) ?? [];\r\n\r\n this._serviceInstances.set(service, await service.factory(...dependencies, abortSignal));\r\n }\r\n\r\n /**\r\n * Resolves a dependency by contract identity for a consuming service.\r\n * Checks local services first, then walks up the parent chain.\r\n * Registers the consumer as a dependent in whichever container owns the dependency.\r\n * @param contract The contract identity to resolve.\r\n * @param consumer The service definition that consumes this dependency.\r\n * @returns The resolved service instance.\r\n */\r\n private _resolveDependency(contract: symbol, consumer: WeaklyTypedServiceDefinition): IService<symbol> & Partial<IDisposable> {\r\n const definition = this._serviceDefinitions.get(contract);\r\n if (definition) {\r\n let dependentDefinitions = this._serviceDependents.get(definition);\r\n if (!dependentDefinitions) {\r\n this._serviceDependents.set(definition, (dependentDefinitions = new Set()));\r\n }\r\n dependentDefinitions.add(consumer);\r\n\r\n const instance = this._serviceInstances.get(definition);\r\n if (!instance) {\r\n throw new Error(`Service '${contract.toString()}' has not been instantiated in the '${this._friendlyName}' container.`);\r\n }\r\n return instance;\r\n }\r\n\r\n if (this._parent) {\r\n return this._parent._resolveDependency(contract, consumer);\r\n }\r\n\r\n throw new Error(`Service '${contract.toString()}' has not been registered in the '${this._friendlyName}' container.`);\r\n }\r\n\r\n /**\r\n * Removes a consumer from the dependent set for a given contract, checking locally first then the parent chain.\r\n * @param contract The contract identity.\r\n * @param consumer The service definition to remove as a dependent.\r\n */\r\n private _removeDependentFromChain(contract: symbol, consumer: WeaklyTypedServiceDefinition): void {\r\n const definition = this._serviceDefinitions.get(contract);\r\n if (definition) {\r\n const dependentDefinitions = this._serviceDependents.get(definition);\r\n if (dependentDefinitions) {\r\n dependentDefinitions.delete(consumer);\r\n if (dependentDefinitions.size === 0) {\r\n this._serviceDependents.delete(definition);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n this._parent?._removeDependentFromChain(contract, consumer);\r\n }\r\n\r\n private _removeService(service: WeaklyTypedServiceDefinition) {\r\n if (this._isDisposed) {\r\n throw new Error(`'${this._friendlyName}' container is disposed.`);\r\n }\r\n\r\n const serviceDependents = this._serviceDependents.get(service);\r\n if (serviceDependents && serviceDependents.size > 0) {\r\n throw new Error(\r\n `Service '${service.friendlyName}' has dependents: ${Array.from(serviceDependents)\r\n .map((dependent) => dependent.friendlyName)\r\n .join(\", \")}`\r\n );\r\n }\r\n\r\n // NOTE: The service instance could be undefined, as the service factory for a service that does not produce any contracts is not required to return an actual service instance.\r\n const serviceInstance = this._serviceInstances.get(service);\r\n this._serviceInstances.delete(service);\r\n serviceInstance?.dispose?.();\r\n\r\n service.produces?.forEach((contract) => {\r\n this._serviceDefinitions.delete(contract);\r\n });\r\n\r\n // Remove this service as a dependent from each of its consumed dependencies (local or in parent chain).\r\n service.consumes?.forEach((contract) => {\r\n this._removeDependentFromChain(contract, service);\r\n });\r\n }\r\n\r\n /**\r\n * Disposes the service container and all contained services.\r\n * Throws if this container is still a parent of any live child containers.\r\n */\r\n public dispose() {\r\n if (this._children.size > 0) {\r\n throw new Error(`'${this._friendlyName}' container cannot be disposed because it has ${this._children.size} active child container(s).`);\r\n }\r\n\r\n Array.from(this._serviceInstances.keys()).reverse().forEach(this._removeService.bind(this));\r\n this._serviceInstances.clear();\r\n this._serviceDependents.clear();\r\n this._serviceDefinitions.clear();\r\n this._parent?._children.delete(this);\r\n this._isDisposed = true;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type IDisposable } from "@babylonjs/core/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* A helper to create a service factory function from a class constructor.
|
|
4
|
+
* @param constructor The class to create a factory function for.
|
|
5
|
+
* @returns A factory function that creates an instance of the class.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ConstructorFactory<Class extends new (...args: any) => any>(constructor: Class): (...args: ConstructorParameters<Class>) => InstanceType<Class>;
|
|
8
|
+
declare const Contract: unique symbol;
|
|
9
|
+
/**
|
|
10
|
+
* This interface must be implemented by all service contracts.
|
|
11
|
+
*/
|
|
12
|
+
export interface IService<ContractIdentity extends symbol> {
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
readonly [Contract]?: ContractIdentity;
|
|
17
|
+
}
|
|
18
|
+
type ExtractContractIdentity<ServiceContract extends IService<symbol>> = ServiceContract extends IService<infer ContractIdentity> ? ContractIdentity : never;
|
|
19
|
+
type ExtractContractIdentities<ServiceContracts extends IService<symbol>[]> = {
|
|
20
|
+
[Index in keyof ServiceContracts]: ExtractContractIdentity<ServiceContracts[Index]>;
|
|
21
|
+
};
|
|
22
|
+
type UnionToIntersection<Union> = (Union extends any ? (k: Union) => void : never) extends (k: infer Intersection) => void ? Intersection : never;
|
|
23
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* A factory function responsible for creating a service instance.
|
|
26
|
+
* Consumed services are passed as arguments to the factory function.
|
|
27
|
+
* The returned value must implement all produced services, and may IDisposable.
|
|
28
|
+
* If not services are produced, the returned value may implement IDisposable, otherwise it may return void.
|
|
29
|
+
*/
|
|
30
|
+
export type ServiceFactory<Produces extends IService<symbol>[], Consumes extends IService<symbol>[]> = (...dependencies: [...Consumes, abortSignal?: AbortSignal]) => MaybePromise<Produces extends [] ? Partial<IDisposable> | void : Partial<IDisposable> & UnionToIntersection<Produces[number]>>;
|
|
31
|
+
/**
|
|
32
|
+
* Defines a service, which is a logical unit that consumes other services (dependencies), and optionally produces services that can be consumed by other services (dependents).
|
|
33
|
+
*/
|
|
34
|
+
export type ServiceDefinition<Produces extends IService<symbol>[] = [], Consumes extends IService<symbol>[] = []> = {
|
|
35
|
+
/**
|
|
36
|
+
* A human readable name for the service to help with debugging.
|
|
37
|
+
*/
|
|
38
|
+
friendlyName: string;
|
|
39
|
+
/**
|
|
40
|
+
* A function that instantiates the service.
|
|
41
|
+
*/
|
|
42
|
+
factory: ServiceFactory<Produces, Consumes>;
|
|
43
|
+
} & (Produces extends [] ? {
|
|
44
|
+
/**
|
|
45
|
+
* An empty list or undefined, since the type specification has indicated no contracts are produced.
|
|
46
|
+
*/
|
|
47
|
+
produces?: [];
|
|
48
|
+
} : {
|
|
49
|
+
/**
|
|
50
|
+
* The list of contract identities that this service produces for consumption by other services.
|
|
51
|
+
*/
|
|
52
|
+
produces: ExtractContractIdentities<Produces>;
|
|
53
|
+
}) & (Consumes extends [] ? {
|
|
54
|
+
/**
|
|
55
|
+
* An empty list or undefined, since the type specification has indicated that no other services are consumed.
|
|
56
|
+
*/
|
|
57
|
+
consumes?: [];
|
|
58
|
+
} : {
|
|
59
|
+
/**
|
|
60
|
+
* The list of contract identities of other services that this service consumes.
|
|
61
|
+
*/
|
|
62
|
+
consumes: ExtractContractIdentities<Consumes>;
|
|
63
|
+
});
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A helper to create a service factory function from a class constructor.
|
|
3
|
+
* @param constructor The class to create a factory function for.
|
|
4
|
+
* @returns A factory function that creates an instance of the class.
|
|
5
|
+
*/
|
|
6
|
+
export function ConstructorFactory(constructor) {
|
|
7
|
+
return (...args) => new constructor(...args);
|
|
8
|
+
}
|
|
9
|
+
// This allows us to map from a service contract back to a contract identity.
|
|
10
|
+
const Contract = Symbol();
|
|
11
|
+
//# sourceMappingURL=serviceDefinition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceDefinition.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/modularTool/modularity/serviceDefinition.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAA0C,WAAkB;IAC1F,OAAO,CAAC,GAAG,IAAkC,EAAE,EAAE,CAAC,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;AAC/E,CAAC;AAED,6EAA6E;AAC7E,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC","sourcesContent":["import { type IDisposable } from \"core/index\";\r\n\r\n/**\r\n * A helper to create a service factory function from a class constructor.\r\n * @param constructor The class to create a factory function for.\r\n * @returns A factory function that creates an instance of the class.\r\n */\r\nexport function ConstructorFactory<Class extends new (...args: any) => any>(constructor: Class): (...args: ConstructorParameters<Class>) => InstanceType<Class> {\r\n return (...args: ConstructorParameters<Class>) => new constructor(...args);\r\n}\r\n\r\n// This allows us to map from a service contract back to a contract identity.\r\nconst Contract = Symbol();\r\n/**\r\n * This interface must be implemented by all service contracts.\r\n */\r\nexport interface IService<ContractIdentity extends symbol> {\r\n /**\r\n * @internal\r\n */\r\n readonly [Contract]?: ContractIdentity;\r\n}\r\n\r\n// This utility type extracts the service identity (unique symbol type) from a service contract. That is, it extracts T from IService<T>.\r\ntype ExtractContractIdentity<ServiceContract extends IService<symbol>> = ServiceContract extends IService<infer ContractIdentity> ? ContractIdentity : never;\r\n\r\n// This utility type extracts the contract identities from an array of service contracts. That is, it extracts [T1, T2, ...] from [IService<T1>, IService<T2>, ...].\r\ntype ExtractContractIdentities<ServiceContracts extends IService<symbol>[]> = {\r\n [Index in keyof ServiceContracts]: ExtractContractIdentity<ServiceContracts[Index]>;\r\n};\r\n\r\n// This utility type converts a union of types into an intersection of types. That is, it converts T1 | T2 | ... into T1 & T2 & ...\r\n// This is specifically used to determine the type that a service factory function returns when it produces multiple services.\r\ntype UnionToIntersection<Union> = (Union extends any ? (k: Union) => void : never) extends (k: infer Intersection) => void ? Intersection : never;\r\n\r\ntype MaybePromise<T> = T | Promise<T>;\r\n\r\n/**\r\n * A factory function responsible for creating a service instance.\r\n * Consumed services are passed as arguments to the factory function.\r\n * The returned value must implement all produced services, and may IDisposable.\r\n * If not services are produced, the returned value may implement IDisposable, otherwise it may return void.\r\n */\r\nexport type ServiceFactory<Produces extends IService<symbol>[], Consumes extends IService<symbol>[]> = (\r\n ...dependencies: [...Consumes, abortSignal?: AbortSignal]\r\n) => MaybePromise<Produces extends [] ? Partial<IDisposable> | void : Partial<IDisposable> & UnionToIntersection<Produces[number]>>;\r\n\r\n/**\r\n * Defines a service, which is a logical unit that consumes other services (dependencies), and optionally produces services that can be consumed by other services (dependents).\r\n */\r\nexport type ServiceDefinition<Produces extends IService<symbol>[] = [], Consumes extends IService<symbol>[] = []> = {\r\n /**\r\n * A human readable name for the service to help with debugging.\r\n */\r\n friendlyName: string;\r\n\r\n /**\r\n * A function that instantiates the service.\r\n */\r\n factory: ServiceFactory<Produces, Consumes>;\r\n} & (Produces extends []\r\n ? {\r\n /**\r\n * An empty list or undefined, since the type specification has indicated no contracts are produced.\r\n */\r\n produces?: [];\r\n }\r\n : {\r\n /**\r\n * The list of contract identities that this service produces for consumption by other services.\r\n */\r\n produces: ExtractContractIdentities<Produces>;\r\n }) &\r\n (Consumes extends []\r\n ? {\r\n /**\r\n * An empty list or undefined, since the type specification has indicated that no other services are consumed.\r\n */\r\n consumes?: [];\r\n }\r\n : {\r\n /**\r\n * The list of contract identities of other services that this service consumes.\r\n */\r\n consumes: ExtractContractIdentities<Consumes>;\r\n });\r\n"]}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Accordion, AccordionHeader, AccordionItem, AccordionPanel, AvatarGroup, AvatarGroupItem, Body1, Body1Strong, Button, Caption1, Card, CardFooter, CardHeader, CardPreview, Dialog, DialogBody, DialogContent, DialogSurface, DialogTitle, DialogTrigger, makeStyles, Persona, Popover, PopoverSurface, PopoverTrigger, PresenceBadge, Spinner, Tab, TabList, tokens, Tooltip, } from "@fluentui/react-components";
|
|
3
|
+
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { ShellServiceIdentity } from "./shellService.js";
|
|
5
|
+
import { AppsAddInRegular, ArrowDownloadRegular, BranchForkRegular, BugRegular, DeleteRegular, DismissRegular, LinkRegular, MailRegular, PeopleCommunityRegular, } from "@fluentui/react-icons";
|
|
6
|
+
import { Fade } from "@fluentui/react-motion-components-preview";
|
|
7
|
+
import { Logger } from "@babylonjs/core/Misc/logger.js";
|
|
8
|
+
import { Link } from "../../fluent/primitives/link.js";
|
|
9
|
+
import { useExtensionManager } from "../contexts/extensionManagerContext.js";
|
|
10
|
+
const useStyles = makeStyles({
|
|
11
|
+
extensionButton: {},
|
|
12
|
+
extensionsDialogSurface: {
|
|
13
|
+
height: "auto",
|
|
14
|
+
width: "70vw",
|
|
15
|
+
maxWidth: "600px",
|
|
16
|
+
maxHeight: "70vh",
|
|
17
|
+
backgroundColor: tokens.colorNeutralBackground2,
|
|
18
|
+
},
|
|
19
|
+
extensionDialogBody: {
|
|
20
|
+
maxWidth: "100%",
|
|
21
|
+
maxHeight: "100%",
|
|
22
|
+
},
|
|
23
|
+
extensionDialogContent: {
|
|
24
|
+
marginLeft: `calc(-1 * ${tokens.spacingHorizontalM})`,
|
|
25
|
+
marginRight: `calc(-1 * ${tokens.spacingHorizontalS})`,
|
|
26
|
+
},
|
|
27
|
+
extensionHeader: {},
|
|
28
|
+
extensionItem: {},
|
|
29
|
+
extensionCardPreview: {
|
|
30
|
+
padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
|
|
31
|
+
display: "flex",
|
|
32
|
+
flexDirection: "column",
|
|
33
|
+
rowGap: tokens.spacingVerticalL,
|
|
34
|
+
},
|
|
35
|
+
extensionIntro: {
|
|
36
|
+
display: "flex",
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
columnGap: tokens.spacingHorizontalM,
|
|
39
|
+
},
|
|
40
|
+
extensionDescription: {
|
|
41
|
+
display: "flex",
|
|
42
|
+
flexDirection: "row",
|
|
43
|
+
columnGap: tokens.spacingHorizontalS,
|
|
44
|
+
},
|
|
45
|
+
extensionButtonContainer: {
|
|
46
|
+
marginLeft: "auto",
|
|
47
|
+
alignSelf: "flex-start",
|
|
48
|
+
},
|
|
49
|
+
spinner: {
|
|
50
|
+
animationDuration: "1s",
|
|
51
|
+
animationName: {
|
|
52
|
+
from: { opacity: 0 },
|
|
53
|
+
to: { opacity: 1 },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
webResourceDiv: {
|
|
57
|
+
display: "flex",
|
|
58
|
+
flexDirection: "column",
|
|
59
|
+
},
|
|
60
|
+
webResourceLink: {
|
|
61
|
+
display: "flex",
|
|
62
|
+
flexDirection: "row",
|
|
63
|
+
columnGap: tokens.spacingHorizontalS,
|
|
64
|
+
alignItems: "center",
|
|
65
|
+
},
|
|
66
|
+
personPopoverSurfaceDiv: {
|
|
67
|
+
display: "flex",
|
|
68
|
+
flexDirection: "column",
|
|
69
|
+
rowGap: tokens.spacingVerticalS,
|
|
70
|
+
},
|
|
71
|
+
accordionHeaderDiv: {
|
|
72
|
+
display: "flex",
|
|
73
|
+
flexDirection: "row",
|
|
74
|
+
columnGap: tokens.spacingHorizontalS,
|
|
75
|
+
alignItems: "center",
|
|
76
|
+
},
|
|
77
|
+
resourceDetailsDiv: {
|
|
78
|
+
display: "flex",
|
|
79
|
+
flexDirection: "column",
|
|
80
|
+
rowGap: tokens.spacingVerticalS,
|
|
81
|
+
},
|
|
82
|
+
peopleDetailsDiv: {
|
|
83
|
+
display: "flex",
|
|
84
|
+
flexDirection: "row",
|
|
85
|
+
columnGap: tokens.spacingHorizontalXL,
|
|
86
|
+
},
|
|
87
|
+
avatarGroupItem: {
|
|
88
|
+
cursor: "pointer",
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
function AsPersonMetadata(person) {
|
|
92
|
+
if (typeof person === "string") {
|
|
93
|
+
return { name: person };
|
|
94
|
+
}
|
|
95
|
+
return person;
|
|
96
|
+
}
|
|
97
|
+
function GetAvatarImage(person) {
|
|
98
|
+
return person.avatar ? { src: `data:image/png;base64,${person.avatar}` } : undefined;
|
|
99
|
+
}
|
|
100
|
+
function usePeopleMetadata(people) {
|
|
101
|
+
const definedPeople = useMemo(() => (people ? people.filter((person) => !!person) : []), [people]);
|
|
102
|
+
return useMemo(() => definedPeople.map(AsPersonMetadata), [definedPeople]);
|
|
103
|
+
}
|
|
104
|
+
const WebResource = (props) => {
|
|
105
|
+
const { url, urlDisplay, icon, label } = props;
|
|
106
|
+
const classes = useStyles();
|
|
107
|
+
return (_jsx("div", { className: classes.webResourceDiv, children: _jsx(Tooltip, { content: label, relationship: "label", positioning: "before", withArrow: true, children: _jsxs("div", { className: classes.webResourceLink, children: [icon, _jsx(Link, { url: url, value: urlDisplay || url })] }) }) }));
|
|
108
|
+
};
|
|
109
|
+
const PersonDetailsPopover = (props) => {
|
|
110
|
+
const { person, title, disabled, children } = props;
|
|
111
|
+
const classes = useStyles();
|
|
112
|
+
if (disabled) {
|
|
113
|
+
return _jsx(_Fragment, { children: children });
|
|
114
|
+
}
|
|
115
|
+
return (_jsxs(Popover, { withArrow: true, children: [_jsx(PopoverTrigger, { disableButtonEnhancement: true, children: children }), _jsx(PopoverSurface, { children: _jsxs("div", { className: classes.personPopoverSurfaceDiv, children: [_jsx(Persona, { name: person.name, secondaryText: title, avatar: { image: GetAvatarImage(person) } }), person.email && _jsx(WebResource, { url: `mailto:${person.email}`, urlDisplay: person.email, icon: _jsx(MailRegular, {}), label: "Email" }), person.url && _jsx(WebResource, { url: person.url, urlDisplay: person.url, icon: _jsx(LinkRegular, {}), label: "Website" }), person.forumUserName && (_jsx(WebResource, { url: `https://forum.babylonjs.com/u/${person.forumUserName}`, urlDisplay: person.forumUserName, icon: _jsx(PeopleCommunityRegular, {}), label: "Forum" }))] }) })] }));
|
|
116
|
+
};
|
|
117
|
+
const ExtensionDetails = memo((props) => {
|
|
118
|
+
const { extension } = props;
|
|
119
|
+
const { metadata } = extension;
|
|
120
|
+
const classes = useStyles();
|
|
121
|
+
const [canInstall, setCanInstall] = useState(false);
|
|
122
|
+
const [canUninstall, setCanUninstall] = useState(false);
|
|
123
|
+
const [isStateChanging, setIsStateChanging] = useState(false);
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
const updateState = () => {
|
|
126
|
+
setCanInstall(!extension.isInstalled && !extension.isStateChanging);
|
|
127
|
+
setCanUninstall(extension.isInstalled && !extension.isStateChanging);
|
|
128
|
+
setIsStateChanging(extension.isStateChanging);
|
|
129
|
+
};
|
|
130
|
+
const stateChangedHandlerRegistration = extension.addStateChangedHandler(updateState);
|
|
131
|
+
updateState();
|
|
132
|
+
return stateChangedHandlerRegistration.dispose;
|
|
133
|
+
}, [extension]);
|
|
134
|
+
const [author] = usePeopleMetadata(useMemo(() => [metadata.author], [metadata.author]));
|
|
135
|
+
const contributors = usePeopleMetadata(metadata.contributors);
|
|
136
|
+
const hasResourceDetails = metadata.homepage || metadata.repository || metadata.bugs;
|
|
137
|
+
const hasPeopleDetails = author || contributors.length > 0;
|
|
138
|
+
const hasPreviewDetails = hasResourceDetails || hasPeopleDetails;
|
|
139
|
+
const hasAuthorDetails = author?.email || author?.url || author?.forumUserName;
|
|
140
|
+
const subHeader = [metadata.version ? `${metadata.version}` : null, metadata.license ? `${metadata.license}` : null].filter(Boolean).join(" | ");
|
|
141
|
+
const install = useCallback(async () => {
|
|
142
|
+
try {
|
|
143
|
+
await extension.installAsync();
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.
|
|
147
|
+
}
|
|
148
|
+
}, [extension]);
|
|
149
|
+
const uninstall = useCallback(async () => {
|
|
150
|
+
try {
|
|
151
|
+
await extension.uninstallAsync();
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.
|
|
155
|
+
}
|
|
156
|
+
}, [extension]);
|
|
157
|
+
return (_jsxs(AccordionItem, { className: classes.extensionItem, value: extension.metadata.name, children: [_jsx(AccordionHeader, { className: classes.extensionHeader, expandIconPosition: "end", children: _jsxs("div", { className: classes.accordionHeaderDiv, children: [_jsx(Body1Strong, { children: extension.metadata.name }), _jsx(Fade, { visible: extension.isInstalled, children: _jsx(PresenceBadge, { size: "small" }) })] }) }), _jsx(AccordionPanel, { children: _jsxs(Card, { children: [_jsx(CardHeader, { header: _jsx(Body1, { children: metadata.description }), description: _jsx(Caption1, { italic: true, children: subHeader }) }), hasPreviewDetails && (_jsxs(CardPreview, { className: classes.extensionCardPreview, children: [hasResourceDetails && (_jsxs("div", { className: classes.resourceDetailsDiv, style: { display: "flex" }, children: [metadata.homepage && _jsx(WebResource, { url: metadata.homepage, icon: _jsx(LinkRegular, {}), label: "Website" }), metadata.repository && _jsx(WebResource, { url: metadata.repository, icon: _jsx(BranchForkRegular, {}), label: "Repository" }), metadata.bugs && _jsx(WebResource, { url: metadata.bugs, icon: _jsx(BugRegular, {}), label: "Report Issues" })] })), hasPeopleDetails && (_jsxs("div", { className: classes.peopleDetailsDiv, style: { display: "flex" }, children: [author && (_jsx(PersonDetailsPopover, { person: author, title: "Author", disabled: !hasAuthorDetails, children: _jsx(Persona, { name: author.name, secondaryText: "Author", avatar: { image: GetAvatarImage(author) }, style: { cursor: hasAuthorDetails ? "pointer" : "default" } }) })), contributors.length > 0 && (_jsx(AvatarGroup, { layout: "stack", children: contributors.map((contributor) => {
|
|
158
|
+
return (_jsx(PersonDetailsPopover, { person: contributor, title: "Contributor", children: _jsx(AvatarGroupItem, { name: contributor.name, className: classes.avatarGroupItem, image: GetAvatarImage(contributor) }) }, contributor.name));
|
|
159
|
+
}) }))] }))] })), _jsxs(CardFooter, { children: [canInstall && (_jsx(Button, { appearance: "primary", size: "small", icon: _jsx(ArrowDownloadRegular, {}), onClick: install, children: "Get" })), canUninstall && (_jsx(Button, { appearance: "secondary", size: "small", icon: _jsx(DeleteRegular, {}), onClick: uninstall, children: "Remove" })), isStateChanging && _jsx(Spinner, { className: classes.spinner, size: "extra-small" })] })] }) })] }));
|
|
160
|
+
});
|
|
161
|
+
export const ExtensionListServiceDefinition = {
|
|
162
|
+
friendlyName: "ExtensionList",
|
|
163
|
+
consumes: [ShellServiceIdentity],
|
|
164
|
+
factory: (shellService) => {
|
|
165
|
+
const registration = shellService.addToolbarItem({
|
|
166
|
+
key: "ExtensionList",
|
|
167
|
+
horizontalLocation: "right",
|
|
168
|
+
verticalLocation: "top",
|
|
169
|
+
teachingMoment: {
|
|
170
|
+
title: "Extensions",
|
|
171
|
+
description: "Extensions provide new optional features that can be useful to your specific task or workflow. Click this button to manage extensions.",
|
|
172
|
+
},
|
|
173
|
+
order: -200,
|
|
174
|
+
component: () => {
|
|
175
|
+
const classes = useStyles();
|
|
176
|
+
const [selectedTab, setSelectedTab] = useState("available");
|
|
177
|
+
const extensionManager = useExtensionManager();
|
|
178
|
+
const [extensions, setExtensions] = useState([]);
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (extensionManager) {
|
|
181
|
+
const populateExtensionsAsync = async () => {
|
|
182
|
+
const query = await extensionManager.queryExtensionsAsync(undefined, undefined, selectedTab === "installed");
|
|
183
|
+
const extensions = await query.getExtensionsAsync(0, query.totalCount);
|
|
184
|
+
setExtensions(extensions);
|
|
185
|
+
};
|
|
186
|
+
// eslint-disable-next-line github/no-then
|
|
187
|
+
populateExtensionsAsync().catch((error) => {
|
|
188
|
+
Logger.Warn(`Failed to populate extensions: ${error}`);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}, [extensionManager, selectedTab]);
|
|
192
|
+
return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { disableButtonEnhancement: true, children: _jsx(Tooltip, { content: "Manage Extensions", relationship: "label", children: _jsx(Button, { className: classes.extensionButton, appearance: "subtle", icon: _jsx(AppsAddInRegular, {}) }) }) }), _jsx(DialogSurface, { className: classes.extensionsDialogSurface, children: _jsxs(DialogBody, { className: classes.extensionDialogBody, children: [_jsx(DialogTitle, { action: _jsx(DialogTrigger, { action: "close", children: _jsx(Button, { appearance: "subtle", "aria-label": "close", icon: _jsx(DismissRegular, {}) }) }), children: _jsxs(_Fragment, { children: ["Extensions", _jsxs(TabList, { className: classes.extensionDialogContent, selectedValue: selectedTab, onTabSelect: (event, data) => {
|
|
193
|
+
setSelectedTab(data.value);
|
|
194
|
+
}, children: [_jsx(Tab, { value: "available", children: "Available" }), _jsx(Tab, { value: "installed", children: "Installed" })] })] }) }), _jsx(DialogContent, { className: classes.extensionDialogContent, children: _jsx(Accordion, { collapsible: true, children: extensions.map((extension) => (_jsx(ExtensionDetails, { extension: extension }, extension.metadata.name))) }) })] }) })] }));
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
return {
|
|
198
|
+
dispose: () => registration.dispose(),
|
|
199
|
+
};
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=extensionsListService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensionsListService.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/modularTool/services/extensionsListService.tsx"],"names":[],"mappings":";AAAA,OAAO,EAGH,SAAS,EACT,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,UAAU,EACV,WAAW,EACX,MAAM,EACN,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,UAAU,EACV,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,aAAa,EACb,OAAO,EACP,GAAG,EACH,OAAO,EACP,MAAM,EACN,OAAO,GACV,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAA0B,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAIhG,OAAO,EAAsB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EACH,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,sBAAsB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,2CAA2C,CAAC;AAEjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,IAAI,EAAE,MAAM,6CAA6C,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE1E,MAAM,SAAS,GAAG,UAAU,CAAC;IACzB,eAAe,EAAE,EAAE;IACnB,uBAAuB,EAAE;QACrB,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,MAAM;QACjB,eAAe,EAAE,MAAM,CAAC,uBAAuB;KAClD;IACD,mBAAmB,EAAE;QACjB,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,MAAM;KACpB;IACD,sBAAsB,EAAE;QACpB,UAAU,EAAE,aAAa,MAAM,CAAC,kBAAkB,GAAG;QACrD,WAAW,EAAE,aAAa,MAAM,CAAC,kBAAkB,GAAG;KACzD;IACD,eAAe,EAAE,EAAE;IACnB,aAAa,EAAE,EAAE;IACjB,oBAAoB,EAAE;QAClB,OAAO,EAAE,GAAG,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,kBAAkB,EAAE;QAClE,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,MAAM,CAAC,gBAAgB;KAClC;IACD,cAAc,EAAE;QACZ,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,QAAQ;QACpB,SAAS,EAAE,MAAM,CAAC,kBAAkB;KACvC;IACD,oBAAoB,EAAE;QAClB,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK;QACpB,SAAS,EAAE,MAAM,CAAC,kBAAkB;KACvC;IACD,wBAAwB,EAAE;QACtB,UAAU,EAAE,MAAM;QAClB,SAAS,EAAE,YAAY;KAC1B;IACD,OAAO,EAAE;QACL,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE;YACX,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;YACpB,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;SACrB;KACJ;IACD,cAAc,EAAE;QACZ,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;KAC1B;IACD,eAAe,EAAE;QACb,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK;QACpB,SAAS,EAAE,MAAM,CAAC,kBAAkB;QACpC,UAAU,EAAE,QAAQ;KACvB;IACD,uBAAuB,EAAE;QACrB,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,MAAM,CAAC,gBAAgB;KAClC;IACD,kBAAkB,EAAE;QAChB,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK;QACpB,SAAS,EAAE,MAAM,CAAC,kBAAkB;QACpC,UAAU,EAAE,QAAQ;KACvB;IACD,kBAAkB,EAAE;QAChB,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,MAAM,CAAC,gBAAgB;KAClC;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,KAAK;QACpB,SAAS,EAAE,MAAM,CAAC,mBAAmB;KACxC;IACD,eAAe,EAAE;QACb,MAAM,EAAE,SAAS;KACpB;CACJ,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,MAA+B;IACrD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,EAA2B,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,MAAsB;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,yBAAyB,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzF,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAyD;IAChF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAqC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACtI,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,WAAW,GAA8F,CAAC,KAAK,EAAE,EAAE;IACrH,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,OAAO,CACH,cAAK,SAAS,EAAE,OAAO,CAAC,cAAc,YAClC,KAAC,OAAO,IAAC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAC,OAAO,EAAC,WAAW,EAAC,QAAQ,EAAC,SAAS,kBACxE,eAAK,SAAS,EAAE,OAAO,CAAC,eAAe,aAClC,IAAI,EACL,KAAC,IAAI,IAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,IAAI,GAAG,GAAI,IAC1C,GACA,GACR,CACT,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAoG,CAAC,KAAK,EAAE,EAAE;IACpI,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACpD,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,4BAAG,QAAQ,GAAI,CAAC;IAC3B,CAAC;IAED,OAAO,CACH,MAAC,OAAO,IAAC,SAAS,mBACd,KAAC,cAAc,IAAC,wBAAwB,kBAAE,QAAQ,GAAkB,EACpE,KAAC,cAAc,cACX,eAAK,SAAS,EAAE,OAAO,CAAC,uBAAuB,aAC3C,KAAC,OAAO,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,GAAI,EAC9F,MAAM,CAAC,KAAK,IAAI,KAAC,WAAW,IAAC,GAAG,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,KAAC,WAAW,KAAG,EAAE,KAAK,EAAC,OAAO,GAAG,EAC7H,MAAM,CAAC,GAAG,IAAI,KAAC,WAAW,IAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,KAAC,WAAW,KAAG,EAAE,KAAK,EAAC,SAAS,GAAG,EAC7G,MAAM,CAAC,aAAa,IAAI,CACrB,KAAC,WAAW,IACR,GAAG,EAAE,iCAAiC,MAAM,CAAC,aAAa,EAAE,EAC5D,UAAU,EAAE,MAAM,CAAC,aAAa,EAChC,IAAI,EAAE,KAAC,sBAAsB,KAAG,EAChC,KAAK,EAAC,OAAO,GACf,CACL,IACC,GACO,IACX,CACb,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAiD,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;IAClF,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAE/B,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9D,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,WAAW,GAAG,GAAG,EAAE;YACrB,aAAa,CAAC,CAAC,SAAS,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YACpE,eAAe,CAAC,SAAS,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YACrE,kBAAkB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAClD,CAAC,CAAC;QAEF,MAAM,+BAA+B,GAAG,SAAS,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACtF,WAAW,EAAE,CAAC;QAEd,OAAO,+BAA+B,CAAC,OAAO,CAAC;IACnD,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,CAAC,MAAM,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,iBAAiB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE9D,MAAM,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,IAAI,CAAC;IACrF,MAAM,gBAAgB,GAAG,MAAM,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3D,MAAM,iBAAiB,GAAG,kBAAkB,IAAI,gBAAgB,CAAC;IACjE,MAAM,gBAAgB,GAAG,MAAM,EAAE,KAAK,IAAI,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,aAAa,CAAC;IAC/E,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEjJ,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACnC,IAAI,CAAC;YACD,MAAM,SAAS,CAAC,YAAY,EAAE,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACL,iGAAiG;QACrG,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC;YACD,MAAM,SAAS,CAAC,cAAc,EAAE,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACL,iGAAiG;QACrG,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,OAAO,CACH,MAAC,aAAa,IAAC,SAAS,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,aAC3E,KAAC,eAAe,IAAC,SAAS,EAAE,OAAO,CAAC,eAAe,EAAE,kBAAkB,EAAC,KAAK,YACzE,eAAK,SAAS,EAAE,OAAO,CAAC,kBAAkB,aACtC,KAAC,WAAW,cAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,GAAe,EACpD,KAAC,IAAI,IAAC,OAAO,EAAE,SAAS,CAAC,WAAW,YAChC,KAAC,aAAa,IAAC,IAAI,EAAC,OAAO,GAAG,GAC3B,IACL,GACQ,EAClB,KAAC,cAAc,cACX,MAAC,IAAI,eACD,KAAC,UAAU,IAAC,MAAM,EAAE,KAAC,KAAK,cAAE,QAAQ,CAAC,WAAW,GAAS,EAAE,WAAW,EAAE,KAAC,QAAQ,IAAC,MAAM,kBAAE,SAAS,GAAY,GAAI,EAClH,iBAAiB,IAAI,CAClB,MAAC,WAAW,IAAC,SAAS,EAAE,OAAO,CAAC,oBAAoB,aAC/C,kBAAkB,IAAI,CACnB,eAAK,SAAS,EAAE,OAAO,CAAC,kBAAkB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aACjE,QAAQ,CAAC,QAAQ,IAAI,KAAC,WAAW,IAAC,GAAG,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAC,WAAW,KAAG,EAAE,KAAK,EAAC,SAAS,GAAG,EACnG,QAAQ,CAAC,UAAU,IAAI,KAAC,WAAW,IAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,EAAE,IAAI,EAAE,KAAC,iBAAiB,KAAG,EAAE,KAAK,EAAC,YAAY,GAAG,EAChH,QAAQ,CAAC,IAAI,IAAI,KAAC,WAAW,IAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAC,UAAU,KAAG,EAAE,KAAK,EAAC,eAAe,GAAG,IAC/F,CACT,EACA,gBAAgB,IAAI,CACjB,eAAK,SAAS,EAAE,OAAO,CAAC,gBAAgB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAC/D,MAAM,IAAI,CACP,KAAC,oBAAoB,IAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,gBAAgB,YAC5E,KAAC,OAAO,IACJ,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,aAAa,EAAC,QAAQ,EACtB,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,EACzC,KAAK,EAAE,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,GAC7D,GACiB,CAC1B,EACA,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CACxB,KAAC,WAAW,IAAC,MAAM,EAAC,OAAO,YACtB,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;gDAC9B,OAAO,CACH,KAAC,oBAAoB,IAAwB,MAAM,EAAE,WAAW,EAAE,KAAK,EAAC,aAAa,YACjF,KAAC,eAAe,IAAC,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,eAAe,EAAE,KAAK,EAAE,cAAc,CAAC,WAAW,CAAC,GAAI,IAD5F,WAAW,CAAC,IAAI,CAEpB,CAC1B,CAAC;4CACN,CAAC,CAAC,GACQ,CACjB,IACC,CACT,IACS,CACjB,EACD,MAAC,UAAU,eACN,UAAU,IAAI,CACX,KAAC,MAAM,IAAC,UAAU,EAAC,SAAS,EAAC,IAAI,EAAC,OAAO,EAAC,IAAI,EAAE,KAAC,oBAAoB,KAAG,EAAE,OAAO,EAAE,OAAO,oBAEjF,CACZ,EACA,YAAY,IAAI,CACb,KAAC,MAAM,IAAC,UAAU,EAAC,WAAW,EAAC,IAAI,EAAC,OAAO,EAAC,IAAI,EAAE,KAAC,aAAa,KAAG,EAAE,OAAO,EAAE,SAAS,uBAE9E,CACZ,EACA,eAAe,IAAI,KAAC,OAAO,IAAC,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAC,aAAa,GAAG,IACrE,IACV,GACM,IACL,CACnB,CAAC;AACN,CAAC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,8BAA8B,GAA2C;IAClF,YAAY,EAAE,eAAe;IAC7B,QAAQ,EAAE,CAAC,oBAAoB,CAAC;IAChC,OAAO,EAAE,CAAC,YAAY,EAAE,EAAE;QACtB,MAAM,YAAY,GAAG,YAAY,CAAC,cAAc,CAAC;YAC7C,GAAG,EAAE,eAAe;YACpB,kBAAkB,EAAE,OAAO;YAC3B,gBAAgB,EAAE,KAAK;YACvB,cAAc,EAAE;gBACZ,KAAK,EAAE,YAAY;gBACnB,WAAW,EAAE,wIAAwI;aACxJ;YACD,KAAK,EAAE,CAAC,GAAG;YACX,SAAS,EAAE,GAAG,EAAE;gBACZ,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;gBAE5B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAW,WAAW,CAAC,CAAC;gBACtE,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;gBAC/C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAe,EAAE,CAAC,CAAC;gBAE/D,SAAS,CAAC,GAAG,EAAE;oBACX,IAAI,gBAAgB,EAAE,CAAC;wBACnB,MAAM,uBAAuB,GAAG,KAAK,IAAI,EAAE;4BACvC,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,oBAAoB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,KAAK,WAAW,CAAC,CAAC;4BAC7G,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;4BACvE,aAAa,CAAC,UAAU,CAAC,CAAC;wBAC9B,CAAC,CAAC;wBAEF,0CAA0C;wBAC1C,uBAAuB,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;4BACtC,MAAM,CAAC,IAAI,CAAC,kCAAkC,KAAK,EAAE,CAAC,CAAC;wBAC3D,CAAC,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC;gBAEpC,OAAO,CACH,MAAC,MAAM,eACH,KAAC,aAAa,IAAC,wBAAwB,kBACnC,KAAC,OAAO,IAAC,OAAO,EAAC,mBAAmB,EAAC,YAAY,EAAC,OAAO,YACrD,KAAC,MAAM,IAAC,SAAS,EAAE,OAAO,CAAC,eAAe,EAAE,UAAU,EAAC,QAAQ,EAAC,IAAI,EAAE,KAAC,gBAAgB,KAAG,GAAI,GACxF,GACE,EAChB,KAAC,aAAa,IAAC,SAAS,EAAE,OAAO,CAAC,uBAAuB,YACrD,MAAC,UAAU,IAAC,SAAS,EAAE,OAAO,CAAC,mBAAmB,aAC9C,KAAC,WAAW,IACR,MAAM,EACF,KAAC,aAAa,IAAC,MAAM,EAAC,OAAO,YACzB,KAAC,MAAM,IAAC,UAAU,EAAC,QAAQ,gBAAY,OAAO,EAAC,IAAI,EAAE,KAAC,cAAc,KAAG,GAAI,GAC/D,YAGpB,4CAEI,MAAC,OAAO,IACJ,SAAS,EAAE,OAAO,CAAC,sBAAsB,EACzC,aAAa,EAAE,WAAW,EAC1B,WAAW,EAAE,CAAC,KAAqB,EAAE,IAAmB,EAAE,EAAE;wDACxD,cAAc,CAAC,IAAI,CAAC,KAAiB,CAAC,CAAC;oDAC3C,CAAC,aAED,KAAC,GAAG,IAAC,KAAK,EAAE,WAA8B,0BAAiB,EAC3D,KAAC,GAAG,IAAC,KAAK,EAAE,WAA8B,0BAAiB,IACrD,IACX,GACO,EACd,KAAC,aAAa,IAAC,SAAS,EAAE,OAAO,CAAC,sBAAsB,YACpD,KAAC,SAAS,IAAC,WAAW,kBACjB,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAC3B,KAAC,gBAAgB,IAA+B,SAAS,EAAE,SAAS,IAA7C,SAAS,CAAC,QAAQ,CAAC,IAAI,CAA0B,CAC3E,CAAC,GACM,GACA,IACP,GACD,IACX,CACZ,CAAC;YACN,CAAC;SACJ,CAAC,CAAC;QAEH,OAAO;YACH,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE;SACxC,CAAC;IACN,CAAC;CACJ,CAAC","sourcesContent":["import {\r\n type SelectTabData,\r\n type SelectTabEvent,\r\n Accordion,\r\n AccordionHeader,\r\n AccordionItem,\r\n AccordionPanel,\r\n AvatarGroup,\r\n AvatarGroupItem,\r\n Body1,\r\n Body1Strong,\r\n Button,\r\n Caption1,\r\n Card,\r\n CardFooter,\r\n CardHeader,\r\n CardPreview,\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogSurface,\r\n DialogTitle,\r\n DialogTrigger,\r\n makeStyles,\r\n Persona,\r\n Popover,\r\n PopoverSurface,\r\n PopoverTrigger,\r\n PresenceBadge,\r\n Spinner,\r\n Tab,\r\n TabList,\r\n tokens,\r\n Tooltip,\r\n} from \"@fluentui/react-components\";\r\nimport { type TriggerProps } from \"@fluentui/react-utilities\";\r\nimport { type FunctionComponent, memo, useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { type PersonMetadata } from \"../extensibility/extensionFeed\";\r\nimport { type IExtension } from \"../extensibility/extensionManager\";\r\nimport { type ServiceDefinition } from \"../modularity/serviceDefinition\";\r\nimport { type IShellService, ShellServiceIdentity } from \"./shellService\";\r\n\r\nimport {\r\n AppsAddInRegular,\r\n ArrowDownloadRegular,\r\n BranchForkRegular,\r\n BugRegular,\r\n DeleteRegular,\r\n DismissRegular,\r\n LinkRegular,\r\n MailRegular,\r\n PeopleCommunityRegular,\r\n} from \"@fluentui/react-icons\";\r\nimport { Fade } from \"@fluentui/react-motion-components-preview\";\r\n\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nimport { Link } from \"shared-ui-components/fluent/primitives/link\";\r\nimport { useExtensionManager } from \"../contexts/extensionManagerContext\";\r\n\r\nconst useStyles = makeStyles({\r\n extensionButton: {},\r\n extensionsDialogSurface: {\r\n height: \"auto\",\r\n width: \"70vw\",\r\n maxWidth: \"600px\",\r\n maxHeight: \"70vh\",\r\n backgroundColor: tokens.colorNeutralBackground2,\r\n },\r\n extensionDialogBody: {\r\n maxWidth: \"100%\",\r\n maxHeight: \"100%\",\r\n },\r\n extensionDialogContent: {\r\n marginLeft: `calc(-1 * ${tokens.spacingHorizontalM})`,\r\n marginRight: `calc(-1 * ${tokens.spacingHorizontalS})`,\r\n },\r\n extensionHeader: {},\r\n extensionItem: {},\r\n extensionCardPreview: {\r\n padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n rowGap: tokens.spacingVerticalL,\r\n },\r\n extensionIntro: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n columnGap: tokens.spacingHorizontalM,\r\n },\r\n extensionDescription: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalS,\r\n },\r\n extensionButtonContainer: {\r\n marginLeft: \"auto\",\r\n alignSelf: \"flex-start\",\r\n },\r\n spinner: {\r\n animationDuration: \"1s\",\r\n animationName: {\r\n from: { opacity: 0 },\r\n to: { opacity: 1 },\r\n },\r\n },\r\n webResourceDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n },\r\n webResourceLink: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalS,\r\n alignItems: \"center\",\r\n },\r\n personPopoverSurfaceDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n rowGap: tokens.spacingVerticalS,\r\n },\r\n accordionHeaderDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalS,\r\n alignItems: \"center\",\r\n },\r\n resourceDetailsDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n rowGap: tokens.spacingVerticalS,\r\n },\r\n peopleDetailsDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalXL,\r\n },\r\n avatarGroupItem: {\r\n cursor: \"pointer\",\r\n },\r\n});\r\n\r\nfunction AsPersonMetadata(person: string | PersonMetadata): PersonMetadata {\r\n if (typeof person === \"string\") {\r\n return { name: person } satisfies PersonMetadata;\r\n }\r\n return person;\r\n}\r\n\r\nfunction GetAvatarImage(person: PersonMetadata): { src: string } | undefined {\r\n return person.avatar ? { src: `data:image/png;base64,${person.avatar}` } : undefined;\r\n}\r\n\r\nfunction usePeopleMetadata(people?: readonly (string | PersonMetadata | undefined)[]): PersonMetadata[] {\r\n const definedPeople = useMemo(() => (people ? people.filter((person): person is string | PersonMetadata => !!person) : []), [people]);\r\n return useMemo(() => definedPeople.map(AsPersonMetadata), [definedPeople]);\r\n}\r\n\r\nconst WebResource: FunctionComponent<{ url: string; urlDisplay?: string; icon: JSX.Element; label: string }> = (props) => {\r\n const { url, urlDisplay, icon, label } = props;\r\n const classes = useStyles();\r\n\r\n return (\r\n <div className={classes.webResourceDiv}>\r\n <Tooltip content={label} relationship=\"label\" positioning=\"before\" withArrow>\r\n <div className={classes.webResourceLink}>\r\n {icon}\r\n <Link url={url} value={urlDisplay || url} />\r\n </div>\r\n </Tooltip>\r\n </div>\r\n );\r\n};\r\n\r\nconst PersonDetailsPopover: FunctionComponent<TriggerProps & { person: PersonMetadata; title: string; disabled?: boolean }> = (props) => {\r\n const { person, title, disabled, children } = props;\r\n const classes = useStyles();\r\n\r\n if (disabled) {\r\n return <>{children}</>;\r\n }\r\n\r\n return (\r\n <Popover withArrow>\r\n <PopoverTrigger disableButtonEnhancement>{children}</PopoverTrigger>\r\n <PopoverSurface>\r\n <div className={classes.personPopoverSurfaceDiv}>\r\n <Persona name={person.name} secondaryText={title} avatar={{ image: GetAvatarImage(person) }} />\r\n {person.email && <WebResource url={`mailto:${person.email}`} urlDisplay={person.email} icon={<MailRegular />} label=\"Email\" />}\r\n {person.url && <WebResource url={person.url} urlDisplay={person.url} icon={<LinkRegular />} label=\"Website\" />}\r\n {person.forumUserName && (\r\n <WebResource\r\n url={`https://forum.babylonjs.com/u/${person.forumUserName}`}\r\n urlDisplay={person.forumUserName}\r\n icon={<PeopleCommunityRegular />}\r\n label=\"Forum\"\r\n />\r\n )}\r\n </div>\r\n </PopoverSurface>\r\n </Popover>\r\n );\r\n};\r\n\r\nconst ExtensionDetails: FunctionComponent<{ extension: IExtension }> = memo((props) => {\r\n const { extension } = props;\r\n const { metadata } = extension;\r\n\r\n const classes = useStyles();\r\n\r\n const [canInstall, setCanInstall] = useState(false);\r\n const [canUninstall, setCanUninstall] = useState(false);\r\n const [isStateChanging, setIsStateChanging] = useState(false);\r\n\r\n useEffect(() => {\r\n const updateState = () => {\r\n setCanInstall(!extension.isInstalled && !extension.isStateChanging);\r\n setCanUninstall(extension.isInstalled && !extension.isStateChanging);\r\n setIsStateChanging(extension.isStateChanging);\r\n };\r\n\r\n const stateChangedHandlerRegistration = extension.addStateChangedHandler(updateState);\r\n updateState();\r\n\r\n return stateChangedHandlerRegistration.dispose;\r\n }, [extension]);\r\n\r\n const [author] = usePeopleMetadata(useMemo(() => [metadata.author], [metadata.author]));\r\n const contributors = usePeopleMetadata(metadata.contributors);\r\n\r\n const hasResourceDetails = metadata.homepage || metadata.repository || metadata.bugs;\r\n const hasPeopleDetails = author || contributors.length > 0;\r\n const hasPreviewDetails = hasResourceDetails || hasPeopleDetails;\r\n const hasAuthorDetails = author?.email || author?.url || author?.forumUserName;\r\n const subHeader = [metadata.version ? `${metadata.version}` : null, metadata.license ? `${metadata.license}` : null].filter(Boolean).join(\" | \");\r\n\r\n const install = useCallback(async () => {\r\n try {\r\n await extension.installAsync();\r\n } catch {\r\n // Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.\r\n }\r\n }, [extension]);\r\n\r\n const uninstall = useCallback(async () => {\r\n try {\r\n await extension.uninstallAsync();\r\n } catch {\r\n // Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.\r\n }\r\n }, [extension]);\r\n\r\n return (\r\n <AccordionItem className={classes.extensionItem} value={extension.metadata.name}>\r\n <AccordionHeader className={classes.extensionHeader} expandIconPosition=\"end\">\r\n <div className={classes.accordionHeaderDiv}>\r\n <Body1Strong>{extension.metadata.name}</Body1Strong>\r\n <Fade visible={extension.isInstalled}>\r\n <PresenceBadge size=\"small\" />\r\n </Fade>\r\n </div>\r\n </AccordionHeader>\r\n <AccordionPanel>\r\n <Card>\r\n <CardHeader header={<Body1>{metadata.description}</Body1>} description={<Caption1 italic>{subHeader}</Caption1>} />\r\n {hasPreviewDetails && (\r\n <CardPreview className={classes.extensionCardPreview}>\r\n {hasResourceDetails && (\r\n <div className={classes.resourceDetailsDiv} style={{ display: \"flex\" }}>\r\n {metadata.homepage && <WebResource url={metadata.homepage} icon={<LinkRegular />} label=\"Website\" />}\r\n {metadata.repository && <WebResource url={metadata.repository} icon={<BranchForkRegular />} label=\"Repository\" />}\r\n {metadata.bugs && <WebResource url={metadata.bugs} icon={<BugRegular />} label=\"Report Issues\" />}\r\n </div>\r\n )}\r\n {hasPeopleDetails && (\r\n <div className={classes.peopleDetailsDiv} style={{ display: \"flex\" }}>\r\n {author && (\r\n <PersonDetailsPopover person={author} title=\"Author\" disabled={!hasAuthorDetails}>\r\n <Persona\r\n name={author.name}\r\n secondaryText=\"Author\"\r\n avatar={{ image: GetAvatarImage(author) }}\r\n style={{ cursor: hasAuthorDetails ? \"pointer\" : \"default\" }}\r\n />\r\n </PersonDetailsPopover>\r\n )}\r\n {contributors.length > 0 && (\r\n <AvatarGroup layout=\"stack\">\r\n {contributors.map((contributor) => {\r\n return (\r\n <PersonDetailsPopover key={contributor.name} person={contributor} title=\"Contributor\">\r\n <AvatarGroupItem name={contributor.name} className={classes.avatarGroupItem} image={GetAvatarImage(contributor)} />\r\n </PersonDetailsPopover>\r\n );\r\n })}\r\n </AvatarGroup>\r\n )}\r\n </div>\r\n )}\r\n </CardPreview>\r\n )}\r\n <CardFooter>\r\n {canInstall && (\r\n <Button appearance=\"primary\" size=\"small\" icon={<ArrowDownloadRegular />} onClick={install}>\r\n Get\r\n </Button>\r\n )}\r\n {canUninstall && (\r\n <Button appearance=\"secondary\" size=\"small\" icon={<DeleteRegular />} onClick={uninstall}>\r\n Remove\r\n </Button>\r\n )}\r\n {isStateChanging && <Spinner className={classes.spinner} size=\"extra-small\" />}\r\n </CardFooter>\r\n </Card>\r\n </AccordionPanel>\r\n </AccordionItem>\r\n );\r\n});\r\n\r\ntype TabValue = \"available\" | \"installed\";\r\n\r\nexport const ExtensionListServiceDefinition: ServiceDefinition<[], [IShellService]> = {\r\n friendlyName: \"ExtensionList\",\r\n consumes: [ShellServiceIdentity],\r\n factory: (shellService) => {\r\n const registration = shellService.addToolbarItem({\r\n key: \"ExtensionList\",\r\n horizontalLocation: \"right\",\r\n verticalLocation: \"top\",\r\n teachingMoment: {\r\n title: \"Extensions\",\r\n description: \"Extensions provide new optional features that can be useful to your specific task or workflow. Click this button to manage extensions.\",\r\n },\r\n order: -200,\r\n component: () => {\r\n const classes = useStyles();\r\n\r\n const [selectedTab, setSelectedTab] = useState<TabValue>(\"available\");\r\n const extensionManager = useExtensionManager();\r\n const [extensions, setExtensions] = useState<IExtension[]>([]);\r\n\r\n useEffect(() => {\r\n if (extensionManager) {\r\n const populateExtensionsAsync = async () => {\r\n const query = await extensionManager.queryExtensionsAsync(undefined, undefined, selectedTab === \"installed\");\r\n const extensions = await query.getExtensionsAsync(0, query.totalCount);\r\n setExtensions(extensions);\r\n };\r\n\r\n // eslint-disable-next-line github/no-then\r\n populateExtensionsAsync().catch((error) => {\r\n Logger.Warn(`Failed to populate extensions: ${error}`);\r\n });\r\n }\r\n }, [extensionManager, selectedTab]);\r\n\r\n return (\r\n <Dialog>\r\n <DialogTrigger disableButtonEnhancement>\r\n <Tooltip content=\"Manage Extensions\" relationship=\"label\">\r\n <Button className={classes.extensionButton} appearance=\"subtle\" icon={<AppsAddInRegular />} />\r\n </Tooltip>\r\n </DialogTrigger>\r\n <DialogSurface className={classes.extensionsDialogSurface}>\r\n <DialogBody className={classes.extensionDialogBody}>\r\n <DialogTitle\r\n action={\r\n <DialogTrigger action=\"close\">\r\n <Button appearance=\"subtle\" aria-label=\"close\" icon={<DismissRegular />} />\r\n </DialogTrigger>\r\n }\r\n >\r\n <>\r\n Extensions\r\n <TabList\r\n className={classes.extensionDialogContent}\r\n selectedValue={selectedTab}\r\n onTabSelect={(event: SelectTabEvent, data: SelectTabData) => {\r\n setSelectedTab(data.value as TabValue);\r\n }}\r\n >\r\n <Tab value={\"available\" satisfies TabValue}>Available</Tab>\r\n <Tab value={\"installed\" satisfies TabValue}>Installed</Tab>\r\n </TabList>\r\n </>\r\n </DialogTitle>\r\n <DialogContent className={classes.extensionDialogContent}>\r\n <Accordion collapsible>\r\n {extensions.map((extension) => (\r\n <ExtensionDetails key={extension.metadata.name} extension={extension} />\r\n ))}\r\n </Accordion>\r\n </DialogContent>\r\n </DialogBody>\r\n </DialogSurface>\r\n </Dialog>\r\n );\r\n },\r\n });\r\n\r\n return {\r\n dispose: () => registration.dispose(),\r\n };\r\n },\r\n};\r\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const CompactModeSettingDescriptor = {
|
|
2
|
+
key: "CompactMode",
|
|
3
|
+
defaultValue: !matchMedia("(pointer: coarse)").matches,
|
|
4
|
+
};
|
|
5
|
+
export const DisableCopySettingDescriptor = {
|
|
6
|
+
key: "DisableCopy",
|
|
7
|
+
defaultValue: false,
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=globalSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globalSettings.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/modularTool/services/globalSettings.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,4BAA4B,GAA+B;IACpE,GAAG,EAAE,aAAa;IAClB,YAAY,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,OAAO;CACzD,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAA+B;IACpE,GAAG,EAAE,aAAa;IAClB,YAAY,EAAE,KAAK;CACtB,CAAC","sourcesContent":["import { type SettingDescriptor } from \"./settingsStore\";\r\n\r\nexport const CompactModeSettingDescriptor: SettingDescriptor<boolean> = {\r\n key: \"CompactMode\",\r\n defaultValue: !matchMedia(\"(pointer: coarse)\").matches,\r\n};\r\n\r\nexport const DisableCopySettingDescriptor: SettingDescriptor<boolean> = {\r\n key: \"DisableCopy\",\r\n defaultValue: false,\r\n};\r\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Context } from "react";
|
|
2
|
+
import { type IDisposable } from "@babylonjs/core/index.js";
|
|
3
|
+
import { type IService } from "../modularity/serviceDefinition.js";
|
|
4
|
+
/**
|
|
5
|
+
* The unique identity symbol for the react context service.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ReactContextServiceIdentity: unique symbol;
|
|
8
|
+
export type ReactContextHandle<T> = IDisposable & {
|
|
9
|
+
updateValue: (newValue: T) => void;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* ReactContextService allows global React contexts to be added/removed/updated.
|
|
13
|
+
*/
|
|
14
|
+
export interface IReactContextService extends IService<typeof ReactContextServiceIdentity> {
|
|
15
|
+
addContext<T>(provider: Context<T>["Provider"], initialValue: T, options?: {
|
|
16
|
+
order?: number;
|
|
17
|
+
}): ReactContextHandle<T>;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactContextService.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/modularTool/services/reactContextService.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC","sourcesContent":["import { type Context } from \"react\";\r\n\r\nimport { type IDisposable } from \"core/index\";\r\nimport { type IService } from \"../modularity/serviceDefinition\";\r\n\r\n/**\r\n * The unique identity symbol for the react context service.\r\n */\r\nexport const ReactContextServiceIdentity = Symbol(\"ReactContextService\");\r\n\r\nexport type ReactContextHandle<T> = IDisposable & {\r\n updateValue: (newValue: T) => void;\r\n};\r\n\r\n/**\r\n * ReactContextService allows global React contexts to be added/removed/updated.\r\n */\r\nexport interface IReactContextService extends IService<typeof ReactContextServiceIdentity> {\r\n addContext<T>(provider: Context<T>[\"Provider\"], initialValue: T, options?: { order?: number }): ReactContextHandle<T>;\r\n}\r\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type IDisposable } from "@babylonjs/core/index.js";
|
|
2
|
+
import { type DynamicAccordionSection, type DynamicAccordionSectionContent } from "../components/extensibleAccordion.js";
|
|
3
|
+
import { type IService, type ServiceDefinition } from "../modularity/serviceDefinition.js";
|
|
4
|
+
import { type IShellService } from "./shellService.js";
|
|
5
|
+
/**
|
|
6
|
+
* The unique identity symbol for the settings service.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SettingsServiceIdentity: unique symbol;
|
|
9
|
+
/**
|
|
10
|
+
* Allows new sections or content to be added to the Settings pane.
|
|
11
|
+
*/
|
|
12
|
+
export interface ISettingsService extends IService<typeof SettingsServiceIdentity> {
|
|
13
|
+
/**
|
|
14
|
+
* Adds a new section to the settings pane.
|
|
15
|
+
* @param section A description of the section to add.
|
|
16
|
+
*/
|
|
17
|
+
addSection(section: DynamicAccordionSection): IDisposable;
|
|
18
|
+
/**
|
|
19
|
+
* Adds content to one or more sections in the settings pane.
|
|
20
|
+
* @param content A description of the content to add.
|
|
21
|
+
*/
|
|
22
|
+
addSectionContent(content: DynamicAccordionSectionContent<unknown>): IDisposable;
|
|
23
|
+
}
|
|
24
|
+
export declare const SettingsServiceDefinition: ServiceDefinition<[ISettingsService], [IShellService]>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ExtensibleAccordion } from "../components/extensibleAccordion.js";
|
|
3
|
+
import { ShellServiceIdentity } from "./shellService.js";
|
|
4
|
+
import { SettingsRegular } from "@fluentui/react-icons";
|
|
5
|
+
import { useObservableCollection, useOrderedObservableCollection } from "../hooks/observableHooks.js";
|
|
6
|
+
import { ObservableCollection } from "../misc/observableCollection.js";
|
|
7
|
+
/**
|
|
8
|
+
* The unique identity symbol for the settings service.
|
|
9
|
+
*/
|
|
10
|
+
export const SettingsServiceIdentity = Symbol("SettingsService");
|
|
11
|
+
export const SettingsServiceDefinition = {
|
|
12
|
+
friendlyName: "Settings",
|
|
13
|
+
consumes: [ShellServiceIdentity],
|
|
14
|
+
produces: [SettingsServiceIdentity],
|
|
15
|
+
factory: (shellService) => {
|
|
16
|
+
const sectionsCollection = new ObservableCollection();
|
|
17
|
+
const sectionContentCollection = new ObservableCollection();
|
|
18
|
+
const registration = shellService.addSidePane({
|
|
19
|
+
key: "Settings",
|
|
20
|
+
title: "Settings",
|
|
21
|
+
icon: SettingsRegular,
|
|
22
|
+
horizontalLocation: "right",
|
|
23
|
+
verticalLocation: "top",
|
|
24
|
+
order: 500,
|
|
25
|
+
teachingMoment: false,
|
|
26
|
+
content: () => {
|
|
27
|
+
const sections = useOrderedObservableCollection(sectionsCollection);
|
|
28
|
+
const sectionContent = useObservableCollection(sectionContentCollection);
|
|
29
|
+
return _jsx(ExtensibleAccordion, { sections: sections, sectionContent: sectionContent, context: true });
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
addSection: (section) => sectionsCollection.add(section),
|
|
34
|
+
addSectionContent: (content) => sectionContentCollection.add(content),
|
|
35
|
+
dispose: () => {
|
|
36
|
+
registration.dispose();
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=settingsService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settingsService.js","sourceRoot":"","sources":["../../../../../dev/sharedUiComponents/src/modularTool/services/settingsService.tsx"],"names":[],"mappings":";AACA,OAAO,EAAqE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE3I,OAAO,EAAsB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAmBjE,MAAM,CAAC,MAAM,yBAAyB,GAA2D;IAC7F,YAAY,EAAE,UAAU;IACxB,QAAQ,EAAE,CAAC,oBAAoB,CAAC;IAChC,QAAQ,EAAE,CAAC,uBAAuB,CAAC;IACnC,OAAO,EAAE,CAAC,YAAY,EAAE,EAAE;QACtB,MAAM,kBAAkB,GAAG,IAAI,oBAAoB,EAA2B,CAAC;QAC/E,MAAM,wBAAwB,GAAG,IAAI,oBAAoB,EAA2C,CAAC;QAErG,MAAM,YAAY,GAAG,YAAY,CAAC,WAAW,CAAC;YAC1C,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,eAAe;YACrB,kBAAkB,EAAE,OAAO;YAC3B,gBAAgB,EAAE,KAAK;YACvB,KAAK,EAAE,GAAG;YACV,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,GAAG,EAAE;gBACV,MAAM,QAAQ,GAAG,8BAA8B,CAAC,kBAAkB,CAAC,CAAC;gBACpE,MAAM,cAAc,GAAG,uBAAuB,CAAC,wBAAwB,CAAC,CAAC;gBAEzE,OAAO,KAAC,mBAAmB,IAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,GAAI,CAAC;YACtG,CAAC;SACJ,CAAC,CAAC;QAEH,OAAO;YACH,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;YACxD,iBAAiB,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC;YACrE,OAAO,EAAE,GAAG,EAAE;gBACV,YAAY,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;SACJ,CAAC;IACN,CAAC;CACJ,CAAC","sourcesContent":["import { type IDisposable } from \"core/index\";\r\nimport { type DynamicAccordionSection, type DynamicAccordionSectionContent, ExtensibleAccordion } from \"../components/extensibleAccordion\";\r\nimport { type IService, type ServiceDefinition } from \"../modularity/serviceDefinition\";\r\nimport { type IShellService, ShellServiceIdentity } from \"./shellService\";\r\n\r\nimport { SettingsRegular } from \"@fluentui/react-icons\";\r\n\r\nimport { useObservableCollection, useOrderedObservableCollection } from \"../hooks/observableHooks\";\r\nimport { ObservableCollection } from \"../misc/observableCollection\";\r\n\r\n/**\r\n * The unique identity symbol for the settings service.\r\n */\r\nexport const SettingsServiceIdentity = Symbol(\"SettingsService\");\r\n\r\n/**\r\n * Allows new sections or content to be added to the Settings pane.\r\n */\r\nexport interface ISettingsService extends IService<typeof SettingsServiceIdentity> {\r\n /**\r\n * Adds a new section to the settings pane.\r\n * @param section A description of the section to add.\r\n */\r\n addSection(section: DynamicAccordionSection): IDisposable;\r\n\r\n /**\r\n * Adds content to one or more sections in the settings pane.\r\n * @param content A description of the content to add.\r\n */\r\n addSectionContent(content: DynamicAccordionSectionContent<unknown>): IDisposable;\r\n}\r\n\r\nexport const SettingsServiceDefinition: ServiceDefinition<[ISettingsService], [IShellService]> = {\r\n friendlyName: \"Settings\",\r\n consumes: [ShellServiceIdentity],\r\n produces: [SettingsServiceIdentity],\r\n factory: (shellService) => {\r\n const sectionsCollection = new ObservableCollection<DynamicAccordionSection>();\r\n const sectionContentCollection = new ObservableCollection<DynamicAccordionSectionContent<unknown>>();\r\n\r\n const registration = shellService.addSidePane({\r\n key: \"Settings\",\r\n title: \"Settings\",\r\n icon: SettingsRegular,\r\n horizontalLocation: \"right\",\r\n verticalLocation: \"top\",\r\n order: 500,\r\n teachingMoment: false,\r\n content: () => {\r\n const sections = useOrderedObservableCollection(sectionsCollection);\r\n const sectionContent = useObservableCollection(sectionContentCollection);\r\n\r\n return <ExtensibleAccordion sections={sections} sectionContent={sectionContent} context={true} />;\r\n },\r\n });\r\n\r\n return {\r\n addSection: (section) => sectionsCollection.add(section),\r\n addSectionContent: (content) => sectionContentCollection.add(content),\r\n dispose: () => {\r\n registration.dispose();\r\n },\r\n };\r\n },\r\n};\r\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type IReadonlyObservable } from "@babylonjs/core/index.js";
|
|
2
|
+
import { type IService } from "../modularity/serviceDefinition.js";
|
|
3
|
+
/**
|
|
4
|
+
* The unique identity symbol for the settings store service.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SettingsStoreIdentity: unique symbol;
|
|
7
|
+
/**
|
|
8
|
+
* Describes a setting by its key and default value.
|
|
9
|
+
*/
|
|
10
|
+
export type SettingDescriptor<T> = {
|
|
11
|
+
/**
|
|
12
|
+
* The unique key used to identify this setting in the store.
|
|
13
|
+
*/
|
|
14
|
+
readonly key: string;
|
|
15
|
+
/**
|
|
16
|
+
* The default value to use when the setting has not been explicitly set.
|
|
17
|
+
*/
|
|
18
|
+
readonly defaultValue: T;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Provides a key-value store for persisting user settings.
|
|
22
|
+
*/
|
|
23
|
+
export interface ISettingsStore extends IService<typeof SettingsStoreIdentity> {
|
|
24
|
+
/**
|
|
25
|
+
* An observable that notifies when a setting has changed, providing the key of the changed setting.
|
|
26
|
+
*/
|
|
27
|
+
onChanged: IReadonlyObservable<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Reads a setting from the store.
|
|
30
|
+
* @param descriptor The descriptor of the setting to read.
|
|
31
|
+
* @returns The current value of the setting, or the default value if it has not been set.
|
|
32
|
+
*/
|
|
33
|
+
readSetting<T>(descriptor: SettingDescriptor<T>): T;
|
|
34
|
+
/**
|
|
35
|
+
* Writes a setting to the store.
|
|
36
|
+
* @param descriptor The descriptor of the setting to write.
|
|
37
|
+
* @param value The value to write.
|
|
38
|
+
*/
|
|
39
|
+
writeSetting<T>(descriptor: SettingDescriptor<T>, value: T): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Default implementation of {@link ISettingsStore} that persists settings using browser local storage.
|
|
43
|
+
*/
|
|
44
|
+
export declare class SettingsStore implements ISettingsStore {
|
|
45
|
+
private readonly _namespace;
|
|
46
|
+
private readonly _onChanged;
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new settings store.
|
|
49
|
+
* @param _namespace A namespace used to scope the settings keys to avoid collisions with other stores.
|
|
50
|
+
*/
|
|
51
|
+
constructor(_namespace: string);
|
|
52
|
+
get onChanged(): IReadonlyObservable<Readonly<string>>;
|
|
53
|
+
readSetting<T>(descriptor: SettingDescriptor<T>): T;
|
|
54
|
+
writeSetting<T>(descriptor: SettingDescriptor<T>, value: T): void;
|
|
55
|
+
}
|