outsystems-ui
Version:
OutSystems UI Framework
274 lines (252 loc) • 8 kB
text/typescript
// eslint-disable-next-line @typescript-eslint/no-unused-vars
namespace OSFramework.OSUI.Patterns {
/**
* Defines the Default props and methods for OutSystemsUI Patterns
*
* @export
* @abstract
* @class AbstractPattern
* @implements {Interface.IPattern}
* @template C
*/
export abstract class AbstractPattern<C extends AbstractConfiguration> implements Interface.IPattern {
// Pattern configurations (doubling as current state). Extends AbstractConfiguration.
private _configs: C;
// Indicates if the pattern has been built or not.
private _isBuilt = false;
// Holds the callback for the onInitialized event
private _platformEventInitialized: GlobalCallbacks.OSGeneric;
// Reference for the base HTML of the element of this pattern;
private _selfElem: HTMLElement;
// Id generated by us, and added to the HTML to uniquely identify a pattern.
private _uniqueId: string;
// Id of the widget. This will be the Id that the developer will be using in runtime.
private _widgetId: string;
// Flag to help on check if a pattern has a provider.
protected isProviderBased = false;
/**
* Creates an instance of AbstractPattern.
*
* @param {string} uniqueId
* @param {C} configs
* @memberof OSFramework.Patterns.AbstractPattern
*/
constructor(uniqueId: string, configs: C) {
this._uniqueId = uniqueId;
this._configs = configs;
}
// Sets the HTML elements, by setting the references and the attributes.
private _setCommonHtmlElements(): void {
this._selfElem = Helper.Dom.GetElementByUniqueId(this._uniqueId);
this._widgetId = this._selfElem.closest(GlobalEnum.DataBlocksTag.DataBlock).id;
if (this._configs.ExtendedClass !== '') {
Helper.Dom.Styles.ExtendedClass(this._selfElem, '', this._configs.ExtendedClass);
}
}
// Unsets the refences to the HTML elements.
private _unsetCommonHtmlElements(): void {
this._selfElem = undefined;
}
/**
* Marks the built as being finished.
*
* @protected
* @memberof OSFramework.Patterns.AbstractPattern
*/
protected finishBuild(): void {
// Check if this is a provider based pattern, If true Initialization cb Event will be triggered at the new provider instance creation.
// For non provider based patterns this should be triggered here.
if (this.isProviderBased === false) {
// Trigger the Initialized Callback Event
this.triggerPlatformInitializedEventCallback();
}
// Set pattern has been build
this._isBuilt = true;
}
/**
* Triggers a generic platform event.
*
* @protected
* @param {GlobalCallbacks.OSGeneric} platFormCallback
* @param {...unknown[]} args
* @memberof AbstractProviderPattern
*/
protected triggerPlatformEventCallback(platFormCallback: GlobalCallbacks.OSGeneric, ...args: unknown[]): void {
if (platFormCallback !== undefined) {
Helper.AsyncInvocation(platFormCallback, this.widgetId, ...args);
}
}
/**
* Trigger the Initialized callback platform event.
*
* @protected
* @memberof AbstractPattern
*/
protected triggerPlatformInitializedEventCallback() {
if (this._platformEventInitialized !== undefined && this._isBuilt === false) {
// Trigger platform's _platformEventInitialized handler.
this.triggerPlatformEventCallback(this._platformEventInitialized);
}
}
/**
* Unsets the global callbacks.
* This naming is used to prevent overriding the unsetCallback method on all patterns
*
* @protected
* @memberof OSFramework.Patterns.AbstractPattern
*/
protected unsetGlobalCallbacks(): void {
this._platformEventInitialized = undefined;
}
/**
* Builds the pattern.
*
* @memberof OSFramework.Patterns.AbstractPattern
*/
public build(): void {
this._setCommonHtmlElements();
}
/**
* Changes the value of the properties in the configurations and
* if changes are to a common property, applies the changes.
*
* @param {string} propertyName
* @param {unknown} propertyValue
* @memberof OSFramework.Patterns.AbstractPattern
*/
public changeProperty(propertyName: string, propertyValue: unknown): void {
if (this._configs.hasOwnProperty(propertyName)) {
if (this._isBuilt) {
switch (propertyName) {
case GlobalEnum.CommonPatternsProperties.ExtendedClass:
Helper.Dom.Styles.ExtendedClass(
this._selfElem,
this._configs.ExtendedClass,
propertyValue as string
);
break;
}
}
//First we used the previous value of the ExtendedClass config.
//then we update it or any other config.
//We also need to validate if the property can be changed.
if (this._configs.validateCanChange(this._isBuilt, propertyName)) {
//If the property can be changed, we then validate if the default value should be applied or not.
this._configs[propertyName] = this._configs.validateDefault(propertyName, propertyValue);
}
} else {
throw new Error(`changeProperty - Property '${propertyName}' can't be changed.`);
}
}
/**
* Disposes the pattern.
*
* @memberof OSFramework.Patterns.AbstractPattern
*/
public dispose(): void {
this._isBuilt = false;
this._unsetCommonHtmlElements();
this.unsetGlobalCallbacks();
this._configs = undefined;
}
/**
* Enables to uniquely identify the pattern in all ways.
*
* @param {string} patternId
* @return {*} {boolean}
* @memberof OSFramework.Patterns.AbstractPattern
*/
public equalsToID(patternId: string): boolean {
return patternId === this._uniqueId || patternId === this._widgetId;
}
/**
* Register a given callback event handler.
*
* @abstract
* @param {string} eventName
* @param {GlobalCallbacks.OSGeneric} callback
* @memberof OSFramework.Patterns.AbstractPattern
*/
public registerCallback(eventName: string, callback: GlobalCallbacks.OSGeneric): void {
switch (eventName) {
case GlobalEnum.ProviderEvents.Initialized:
if (this._platformEventInitialized === undefined) {
this._platformEventInitialized = callback;
}
break;
default:
console.warn(
`The pattern with id '${this.widgetId}' does not have the event '${eventName}' defined.`
);
}
}
/**
* Getter that allows to obtain the accessibility is enabled.
*
* @readonly
* @protected
* @type {boolean}
* @memberof OSFramework.Patterns.AbstractPattern
*/
//TODO: getter to remove.
protected get _enableAccessibility(): boolean {
return Helper.DeviceInfo.HasAccessibilityEnabled;
}
/**
* Getter that allows to obtain the self element.
*
* @readonly
* @type {(HTMLElement | undefined)}
* @memberof OSFramework.Patterns.AbstractPattern
*/
public get selfElement(): HTMLElement {
return this._selfElem;
}
/**
* Getter that tells if the pattern is already built.
*
* @readonly
* @type {boolean}
* @memberof OSFramework.Patterns.AbstractPattern
*/
public get isBuilt(): boolean {
return this._isBuilt;
}
/**
* Current configurations/state of the pattern.
*
* @readonly
* @type {C}
* @memberof OSFramework.Patterns.AbstractPattern
*/
public get configs(): C {
return this._configs;
}
/**
* Unique id of the pattern. Internal use only.
*
* @readonly
* @type {string}
* @memberof OSFramework.Patterns.AbstractPattern
*/
public get uniqueId(): string {
return this._uniqueId;
}
/**
* Id of the pattern known by the developer. External use only.
*
* @readonly
* @type {string}
* @memberof OSFramework.Patterns.AbstractPattern
*/
public get widgetId(): string {
return this._widgetId;
}
// Common methods all patterns must implement
protected abstract setA11YProperties(): void;
protected abstract setCallbacks(): void;
protected abstract setHtmlElements(): void;
protected abstract unsetCallbacks(): void;
protected abstract unsetHtmlElements(): void;
}
}