fixed problem

This commit is contained in:
Niels Lyngsø
2023-11-15 21:35:24 +01:00
parent 7bd77e8cdb
commit 7e4d372c42
4 changed files with 81 additions and 49 deletions

View File

@@ -5,6 +5,7 @@ import {
type ManifestWithDynamicConditions,
type UmbExtensionRegistry,
createExtensionApi,
UmbConditionConfigBase,
} from '@umbraco-cms/backoffice/extension-api';
import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
@@ -12,6 +13,7 @@ export abstract class UmbBaseExtensionInitializer<
ManifestType extends ManifestWithDynamicConditions = ManifestWithDynamicConditions,
SubClassType = never,
> extends UmbBaseController {
//
#promiseResolvers: Array<() => void> = [];
#manifestObserver!: UmbObserverController<ManifestType | undefined>;
#extensionRegistry: UmbExtensionRegistry<ManifestCondition>;
@@ -74,7 +76,7 @@ export abstract class UmbBaseExtensionInitializer<
this.#overwrites = extensionManifest.overwrites;
}
}
this.#gotConditions();
this.#gotManifest();
} else {
this.#overwrites = [];
this.#cleanConditions();
@@ -90,16 +92,17 @@ export abstract class UmbBaseExtensionInitializer<
}
#cleanConditions() {
if (this.#conditionControllers.length === 0) return;
this.#conditionControllers.forEach((controller) => controller.destroy());
this.#conditionControllers = [];
this.removeControllerByAlias('_observeConditions');
}
#gotConditions() {
#gotManifest() {
const conditionConfigs = this.#manifest?.conditions ?? [];
// As conditionConfigs might have been configured as something else than an array, then we ignorer them.
if (conditionConfigs.length === undefined || conditionConfigs.length === 0) {
if (conditionConfigs.length === 0) {
this.#cleanConditions();
this.#onConditionsChangedCallback();
return;
@@ -131,41 +134,7 @@ export abstract class UmbBaseExtensionInitializer<
// Observes the conditions and initialize as they come in.
this.observe(
this.#extensionRegistry.getByTypeAndAliases('condition', conditionAliases),
async (manifests) => {
const oldLength = this.#conditionControllers.length;
// New comers:
manifests.forEach((conditionManifest) => {
const configsOfThisType = conditionConfigs.filter(
(conditionConfig) => conditionConfig.alias === conditionManifest.alias,
);
// Spin up conditions, based of condition configs:
configsOfThisType.forEach(async (conditionConfig) => {
// Check if we already have a controller for this config:
const existing = this.#conditionControllers.find((controller) => controller.config === conditionConfig);
if (!existing) {
const conditionController = await createExtensionApi(conditionManifest, [
{
host: this,
manifest: conditionManifest,
config: conditionConfig,
onChange: this.#onConditionsChangedCallback,
},
]);
if (conditionController) {
// Some how listen to it? callback/event/onChange something.
this.#conditionControllers.push(conditionController);
}
}
});
});
// If a change to amount of condition controllers, this will make sure that when new conditions are added, the callback is fired, so the extensions can be re-evaluated, starting out as bad.
if (oldLength !== this.#conditionControllers.length) {
this.#onConditionsChangedCallback();
}
},
this.#gotConditions,
'_observeConditions',
);
} else {
@@ -178,6 +147,67 @@ export abstract class UmbBaseExtensionInitializer<
}
}
#gotConditions = (manifests: ManifestCondition[]) => {
manifests.forEach(this.#gotCondition);
};
#gotCondition = async (conditionManifest: ManifestCondition) => {
const conditionConfigs = this.#manifest?.conditions ?? [];
//
// Get just the conditions that uses this condition alias:
const configsOfThisType = conditionConfigs.filter(
(conditionConfig) => conditionConfig.alias === conditionManifest.alias,
);
// Create conditions, based of condition configs:
const newConditionControllers = await Promise.all(
configsOfThisType.map((conditionConfig) => this.#createConditionController(conditionManifest, conditionConfig)),
);
const oldLength = this.#conditionControllers.length;
newConditionControllers
.filter((x) => x !== undefined)
.forEach((emerging) => {
// TODO: All of this could use a refactor at one point, when someone is fresh in their mind.
// Niels Notes: Current problem being that we are not aware about what is in the making, so we don't know if we end up creating the same condition multiple times.
// Because it took some time to create the conditions, it maybe have already gotten created by another cycle, so lets test again.
const existing = this.#conditionControllers.find((existing) => existing.config === emerging?.config);
if (!existing) {
this.#conditionControllers.push(emerging!);
} else {
emerging?.destroy();
}
});
// If a change to amount of condition controllers, this will make sure that when new conditions are added, the callback is fired, so the extensions can be re-evaluated, starting out as bad.
if (oldLength !== this.#conditionControllers.length) {
this.#onConditionsChangedCallback();
}
};
async #createConditionController(
conditionManifest: ManifestCondition,
conditionConfig: UmbConditionConfigBase,
): Promise<UmbExtensionCondition | undefined> {
// Check if we already have a controller for this config:
const existing = this.#conditionControllers.find((controller) => controller.config === conditionConfig);
if (!existing) {
const conditionController = await createExtensionApi(conditionManifest, [
{
host: this,
manifest: conditionManifest,
config: conditionConfig,
onChange: this.#onConditionsChangedCallback,
},
]);
if (conditionController) {
return conditionController;
}
}
return undefined;
}
#conditionsAreInitialized() {
// Not good if we don't have a manifest.
// Only good if conditions of manifest is equal to the amount of condition controllers (one for each condition).

View File

@@ -6,7 +6,6 @@ import type {
UmbExtensionRegistry,
} from '@umbraco-cms/backoffice/extension-api';
import { UmbBaseController, type UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
export type PermittedControllerType<ControllerType extends { manifest: any }> = ControllerType & {
manifest: Required<Pick<ControllerType, 'manifest'>>;
@@ -70,9 +69,9 @@ export abstract class UmbBaseExtensionsInitializer<
}
// Clean up extensions that are no longer.
this._extensions = this._extensions.filter((controller) => {
if (!manifests.find((manifest) => manifest.alias === controller.alias)) {
controller.destroy();
this._extensions = this._extensions.filter((extension) => {
if (!manifests.find((manifest) => manifest.alias === extension.alias)) {
extension.destroy();
// destroying the controller will, if permitted, make a last callback with isPermitted = false. This will also remove it from the _permittedExts array.
return false;
}

View File

@@ -1,5 +1,8 @@
import type { ManifestTypeMap, SpecificManifestTypeOrManifestBase } from '../types/map.types.js';
import { type PermittedControllerType, UmbBaseExtensionsInitializer } from './base-extensions-initializer.controller.js';
import {
type PermittedControllerType,
UmbBaseExtensionsInitializer,
} from './base-extensions-initializer.controller.js';
import {
type ManifestBase,
UmbExtensionElementInitializer,
@@ -11,10 +14,10 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
*/
export class UmbExtensionsElementInitializer<
ManifestTypes extends ManifestBase,
ManifestTypeName extends keyof ManifestTypeMap<ManifestTypes> | string = ManifestTypes["type"],
ManifestTypeName extends keyof ManifestTypeMap<ManifestTypes> | string = ManifestTypes['type'],
ManifestType extends ManifestBase = SpecificManifestTypeOrManifestBase<ManifestTypes, ManifestTypeName>,
ControllerType extends UmbExtensionElementInitializer<ManifestType> = UmbExtensionElementInitializer<ManifestType>,
MyPermittedControllerType extends ControllerType = PermittedControllerType<ControllerType>
MyPermittedControllerType extends ControllerType = PermittedControllerType<ControllerType>,
> extends UmbBaseExtensionsInitializer<
ManifestTypes,
ManifestTypeName,
@@ -43,7 +46,7 @@ export class UmbExtensionsElementInitializer<
type: ManifestTypeName | Array<ManifestTypeName>,
filter: undefined | null | ((manifest: ManifestType) => boolean),
onChange: (permittedManifests: Array<MyPermittedControllerType>) => void,
defaultElement?: string
defaultElement?: string,
) {
super(host, extensionRegistry, type, filter, onChange);
this.#extensionRegistry = extensionRegistry;
@@ -57,7 +60,7 @@ export class UmbExtensionsElementInitializer<
this.#extensionRegistry,
manifest.alias,
this._extensionChanged,
this._defaultElement
this._defaultElement,
) as ControllerType;
extController.properties = this.#props;

View File

@@ -1,6 +1,6 @@
import type { UmbWorkspaceElement } from '../workspace/workspace.element.js';
import type { UmbSectionMainViewElement } from './section-main-views/section-main-views.element.js';
import { UmbTextStyles } from "@umbraco-cms/backoffice/style";
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, nothing, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import {
ManifestSection,
@@ -82,7 +82,7 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio
${repeat(
this._sidebarApps,
(app) => app.alias,
(app) => app.component
(app) => app.component,
)}
</umb-section-sidebar>
`