diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f20ee..576f5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,4 +89,13 @@ Inital commit, which is working with the browser # 1.0.36 - Fixes: - - Small fixes in the imports of some items in `module.BaseModule.injectable`; `module.GenericWrapper.injectable`; `helpers.descriptors` to make shure, the `nope.d.ts` for the browser is compiled. \ No newline at end of file + - Small fixes in the imports of some items in `module.BaseModule.injectable`; `module.GenericWrapper.injectable`; `helpers.descriptors` to make shure, the `nope.d.ts` for the browser is compiled. + +# 1.1.0 +- Added: + - Added gui defintion files in `types.ui` containing: + - rendering callback options + - base layout based helpers, + - provided libraries + - Added dev-depencies for libraries. + - added `ui.loader` a backend component to readin the ui. diff --git a/contribute/VERSION b/contribute/VERSION index d1c66e6..04a535c 100644 --- a/contribute/VERSION +++ b/contribute/VERSION @@ -1 +1 @@ -1.0.36 \ No newline at end of file +1.1.00 \ No newline at end of file diff --git a/lib/loader/nopePackageLoader.ts b/lib/loader/nopePackageLoader.ts index 634dc45..1fdabde 100644 --- a/lib/loader/nopePackageLoader.ts +++ b/lib/loader/nopePackageLoader.ts @@ -15,7 +15,7 @@ import { DISPATCHER_INSTANCE } from "../symbols/identifiers"; import { INopeDispatcher } from "../types/nope/nopeDispatcher.interface"; import { INopeModule } from "../types/nope/nopeModule.interface"; import { - IDescriptor, + IClassDescriptor, INopeActivationHanlder, IPackageDescription, } from "../types/nope/nopePackage.interface"; @@ -104,9 +104,12 @@ export class NopePackageLoader implements INopePackageLoader { return _element; } - public availableElements: IDescriptor[]; + public availableElements: IClassDescriptor[]; - protected _compareElements(_a: IDescriptor, _b: IDescriptor): boolean { + protected _compareElements( + _a: IClassDescriptor, + _b: IClassDescriptor + ): boolean { if ( _a.options && _a.options.addition && @@ -125,11 +128,11 @@ export class NopePackageLoader implements INopePackageLoader { * Internal Method to Test, whether an Element exists or not. * * @protected - * @param {IDescriptor} _item + * @param {IClassDescriptor} _item * @return {*} {boolean} * @memberof NopePackageLoader */ - protected _hasElement(_item: IDescriptor): boolean { + protected _hasElement(_item: IClassDescriptor): boolean { for (const _element of this.availableElements) { try { if (Array.isArray(_element.selector)) { @@ -171,11 +174,11 @@ export class NopePackageLoader implements INopePackageLoader { /** * Method to add an Element to the Build * - * @param {IDescriptor[]} _elements Definition containing the Elements that should be added + * @param {IClassDescriptor[]} _elements Definition containing the Elements that should be added * @memberof NopePackageLoader */ public async addDescription( - _elements: IDescriptor[], + _elements: IClassDescriptor[], _instance: NopePackageLoader | null = null ): Promise { if (_instance === null) { @@ -207,12 +210,12 @@ export class NopePackageLoader implements INopePackageLoader { * Internal Helper Function to Merge an external Builder for creating Tasks. * * @protected - * @param {IDescriptor} _element + * @param {IClassDescriptor} _element * @param {NopePackageLoader} _instance * @memberof NopePackageLoader */ protected _linkExternalBuilder( - _element: IDescriptor, + _element: IClassDescriptor, _instance: NopePackageLoader ): void { // Bind Factory @@ -248,10 +251,10 @@ export class NopePackageLoader implements INopePackageLoader { * Internal Funcitont to add an Description. * * @protected - * @param {IDescriptor} _element + * @param {IClassDescriptor} _element * @memberof NopePackageLoader */ - protected _addElement(_element: IDescriptor): void { + protected _addElement(_element: IClassDescriptor): void { if (_element) { const _this = this; @@ -499,7 +502,7 @@ export class NopePackageLoader implements INopePackageLoader { this.container.bind("global.config").toConstantValue(_globalConfig); - this.availableElements = new Array(); + this.availableElements = new Array(); } constructor() { diff --git a/lib/types/index.ts b/lib/types/index.ts index adf01c9..67fa94e 100644 --- a/lib/types/index.ts +++ b/lib/types/index.ts @@ -5,6 +5,7 @@ */ import * as nope from "./nope/index"; +import * as ui from "./ui/index"; export * from "./nope/index"; export * from "./IJSONSchema"; -export { nope }; +export { nope, ui }; diff --git a/lib/types/nope/nopeModule.interface.ts b/lib/types/nope/nopeModule.interface.ts index e0ac560..278eed7 100644 --- a/lib/types/nope/nopeModule.interface.ts +++ b/lib/types/nope/nopeModule.interface.ts @@ -1,11 +1,10 @@ /** * @author Martin Karkowski * @email m.karkowski@zema.de - * @create date 2020-10-12 17:38:15 - * @modify date 2020-12-30 10:20:03 * @desc Defintion of a generic Module. */ +import { TRenderConfigureServicePage } from "../ui"; import { ICallOptions } from "./nopeCommunication.interface"; import { INopeDescriptor } from "./nopeDescriptor.interface"; import { INopeObservable } from "./nopeObservable.interface"; @@ -39,7 +38,7 @@ export interface INopeModuleDescription { * Name of the Module. The name of the module must be written in lowercase. * * @type {string} - * @memberof IBaseModule + * @memberof INopeModuleDescription */ identifier: string; @@ -47,7 +46,7 @@ export interface INopeModuleDescription { * Type of the Module * * @type {string} - * @memberof INopeModule + * @memberof INopeModuleDescription */ readonly type: string; @@ -58,7 +57,7 @@ export interface INopeModuleDescription { * will be offered in the Network, provide a meaning full documentation * * @type {string} - * @memberof IBaseModule + * @memberof INopeModuleDescription */ description: string; @@ -66,7 +65,7 @@ export interface INopeModuleDescription { * The Author of the Module * * @type {IAuthor} - * @memberof IBaseModule + * @memberof INopeModuleDescription */ author: IAuthor; @@ -74,10 +73,18 @@ export interface INopeModuleDescription { * Description of the provided Version of the Module. * * @type {IVersion} - * @memberof IBaseModule + * @memberof INopeModuleDescription */ version: IVersion; + /** + * Contains the provided functions. + * + * > **key** = `id` of the function + * + * @type {{ [index: string]: IFunctionOptions }} + * @memberof INopeModuleDescription + */ readonly functions: { [index: string]: IFunctionOptions }; readonly events: { [index: string]: IEventOptions }; @@ -127,10 +134,9 @@ export interface INopeModule extends INopeModuleDescription { * Function to Register a Property. If called for an existing Property, the Data will be * updated. * - * @template T - * @template K - * @template S - * @template G + * @template T Internal Type + * @template S Setter Type + * @template G Getter Type * @param {string} name Name of the Property. * @param {INopeObservable} observable The Observable. * @param {IEventOptions} options The Options which are used during registering the Observable. @@ -147,7 +153,7 @@ export interface INopeModule extends INopeModuleDescription { * Function used to unregister a Property * * @param {string} name Name of the Property. - * @return {*} {Promise} + * @return {Promise} * @memberof IBaseModule */ unregisterProperty(name: string): Promise; @@ -156,7 +162,7 @@ export interface INopeModule extends INopeModuleDescription { * Function to list the available Functions of the module. This will hold all available functions * (dynamic and static functions). * - * @return {*} {Promise>} + * @return {Promise>} * @memberof IBaseModule */ listFunctions(): Promise< @@ -166,7 +172,7 @@ export interface INopeModule extends INopeModuleDescription { /** * Function used to get an List of all registered Properties. * - * @return {*} {Promise>} + * @return {Promise>} * @memberof IBaseModule */ listProperties(): Promise< @@ -176,7 +182,7 @@ export interface INopeModule extends INopeModuleDescription { /** * Function used to initialze the Module. * - * @return {*} {Promise} + * @return {Promise} * @memberof IBaseModule */ init(...args): Promise; @@ -184,7 +190,7 @@ export interface INopeModule extends INopeModuleDescription { /** * Function used to Dispose the Module. * - * @return {*} {Promise} + * @return {Promise} * @memberof IBaseModule */ dispose(): Promise; @@ -192,7 +198,7 @@ export interface INopeModule extends INopeModuleDescription { /** * Function used to derive a parsable Description of the Module. * - * @return {*} {INopeModuleDescription} + * @return {INopeModuleDescription} * @memberof INopeModule */ toDescription(): INopeModuleDescription; @@ -231,7 +237,6 @@ export interface IGenericNopeModule extends INopeModule { * * @export * @interface IEventOptions - * @template K */ export interface IEventOptions { /** @@ -272,7 +277,7 @@ export interface IEventOptions { * @export * @interface IFunctionOptions */ -export interface IFunctionOptions extends Partial { +export interface IFunctionOptions extends Partial { /** * Instead of generating a uuid an id could be provided * @@ -289,6 +294,13 @@ export interface IFunctionOptions extends Partial { */ schema: INopeDescriptor; + /** + * The ui definition of the service. + */ + ui?: { + serviceConfiguration?: TRenderConfigureServicePage; + }; + /** * Flag, to indicate, that the Item is dynamic. * diff --git a/lib/types/nope/nopePackage.interface.ts b/lib/types/nope/nopePackage.interface.ts index 6faf758..db5d00e 100644 --- a/lib/types/nope/nopePackage.interface.ts +++ b/lib/types/nope/nopePackage.interface.ts @@ -1,9 +1,10 @@ import { interfaces } from "inversify"; +import { TCreatorPage, TRenderInstancePage } from "../ui"; import { IInstanceCreationMsg } from "./nopeCommunication.interface"; import { IValidPromise } from "./nopeDispatcher.interface"; -import { IFunctionOptions } from "./nopeModule.interface"; +import { IFunctionOptions, INopeModule } from "./nopeModule.interface"; -export interface IDescriptor { +export interface IClassDescriptor { /** * Identifier for a Single Element * @@ -44,7 +45,7 @@ export interface IDescriptor { name: "whenTargetTagged" | "whenTargetNamed" | "onActivation"; args: any[]; }; - factoryCallback?: (context: interfaces.Context) => (...args) => any; + factoryCallback?: (context: interfaces.Context) => (...args) => T; }; /** @@ -70,15 +71,19 @@ export interface IPackageDescription< /** * Element containing the classes of the module. * - * @type {Array} + * @type {Array} * @memberof IPackageDescription */ providedClasses: Array<{ - description: IDescriptor; + description: IClassDescriptor; settings: { allowInstanceGeneration?: boolean; maxAmountOfInstance?: number; }; + ui?: { + creator: TCreatorPage; + config: TRenderInstancePage; + }; }>; /** diff --git a/lib/types/nope/nopePackageLoader.interface.ts b/lib/types/nope/nopePackageLoader.interface.ts index ea43c4c..61ba6de 100644 --- a/lib/types/nope/nopePackageLoader.interface.ts +++ b/lib/types/nope/nopePackageLoader.interface.ts @@ -1,7 +1,7 @@ import { Container } from "inversify"; import { INopeDispatcher } from "./nopeDispatcher.interface"; import { - IDescriptor, + IClassDescriptor, INopeActivationHanlder, IPackageDescription, } from "./nopePackage.interface"; @@ -30,11 +30,11 @@ export interface INopePackageLoader { /** * Add a Description * - * @param {Array} the Descriptions as Array. + * @param {Array} the Descriptions as Array. * @return {*} {Promise} * @memberof INopePackageLoader */ - addDescription(element: Array): Promise; + addDescription(element: Array): Promise; /** * Function to add Activation Handlers. diff --git a/lib/types/ui/editor/IEdges.ts b/lib/types/ui/editor/IEdges.ts new file mode 100644 index 0000000..d417060 --- /dev/null +++ b/lib/types/ui/editor/IEdges.ts @@ -0,0 +1,91 @@ +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +export type EDGE_TYPE_INFO_CONSUME_DATA = "info:consume:data"; +export type EDGE_TYPE_INFO_CONSUME_EVENT = "info:consume:event"; +export type EDGE_TYPE_INFO_CONSUME_PATH = "info:consume:path"; +export type EDGE_TYPE_INFO_IS_SUB_INFO = "info:is-child"; +export type EDGE_TYPE_LOGIC_AVOIDS = "logic:avoid"; +export type EDGE_TYPE_LOGIC_CONSUME_TOKEN = "logic:token:consume"; +export type EDGE_TYPE_LOGIC_PRODUCE_TOKEN = "logic:token:produce"; +export type EDGE_TYPE_LOGIC_RELEASES = "logic:release"; +export type EDGE_TYPE_LOGIC_REMOVE_RELEASES = "logic:lock"; +export type EDGE_TYPE_LOGIC_REQUIRES = "logic:require"; +export type EDGE_TYPE_LOGIC_TRIGGERS = "logic:trigger"; +export type EDGE_TYPE_PLANNER_AVOIDS = "logic:planner:avoids"; +export type EDGE_TYPE_PLANNER_LEADS_TO = "logic:planner:leads-to"; +export type EDGE_TYPE_PLANNER_RELEASES = "logic:planner:releases"; +export type EDGE_TYPE_PLANNER_REQUIRES = "logic:planner:requires"; +export type VALID_EDGES = + | EDGE_TYPE_INFO_CONSUME_DATA + | EDGE_TYPE_INFO_CONSUME_EVENT + | EDGE_TYPE_INFO_CONSUME_PATH + | EDGE_TYPE_INFO_IS_SUB_INFO + | EDGE_TYPE_LOGIC_AVOIDS + | EDGE_TYPE_LOGIC_CONSUME_TOKEN + | EDGE_TYPE_LOGIC_PRODUCE_TOKEN + | EDGE_TYPE_LOGIC_RELEASES + | EDGE_TYPE_LOGIC_REMOVE_RELEASES + | EDGE_TYPE_LOGIC_REQUIRES + | EDGE_TYPE_LOGIC_TRIGGERS + | EDGE_TYPE_PLANNER_AVOIDS + | EDGE_TYPE_PLANNER_LEADS_TO + | EDGE_TYPE_PLANNER_RELEASES + | EDGE_TYPE_PLANNER_REQUIRES; + +export const EDGE_TYPE_INFO_CONSUME_DATA: EDGE_TYPE_INFO_CONSUME_DATA = + "info:consume:data"; +export const EDGE_TYPE_INFO_CONSUME_EVENT: EDGE_TYPE_INFO_CONSUME_EVENT = + "info:consume:event"; +export const EDGE_TYPE_INFO_CONSUME_PATH: EDGE_TYPE_INFO_CONSUME_PATH = + "info:consume:path"; +export const EDGE_TYPE_INFO_IS_SUB_INFO: EDGE_TYPE_INFO_IS_SUB_INFO = + "info:is-child"; +export const EDGE_TYPE_LOGIC_AVOIDS: EDGE_TYPE_LOGIC_AVOIDS = "logic:avoid"; +export const EDGE_TYPE_LOGIC_CONSUME_TOKEN: EDGE_TYPE_LOGIC_CONSUME_TOKEN = + "logic:token:consume"; +export const EDGE_TYPE_LOGIC_PRODUCE_TOKEN: EDGE_TYPE_LOGIC_PRODUCE_TOKEN = + "logic:token:produce"; +export const EDGE_TYPE_LOGIC_RELEASES: EDGE_TYPE_LOGIC_RELEASES = + "logic:release"; +export const EDGE_TYPE_LOGIC_REMOVE_RELEASES: EDGE_TYPE_LOGIC_REMOVE_RELEASES = + "logic:lock"; +export const EDGE_TYPE_LOGIC_REQUIRES: EDGE_TYPE_LOGIC_REQUIRES = + "logic:require"; +export const EDGE_TYPE_LOGIC_TRIGGERS: EDGE_TYPE_LOGIC_TRIGGERS = + "logic:trigger"; +export const EDGE_TYPE_PLANNER_AVOIDS: EDGE_TYPE_PLANNER_AVOIDS = + "logic:planner:avoids"; +export const EDGE_TYPE_PLANNER_LEADS_TO: EDGE_TYPE_PLANNER_LEADS_TO = + "logic:planner:leads-to"; +export const EDGE_TYPE_PLANNER_RELEASES: EDGE_TYPE_PLANNER_RELEASES = + "logic:planner:releases"; +export const EDGE_TYPE_PLANNER_REQUIRES: EDGE_TYPE_PLANNER_REQUIRES = + "logic:planner:requires"; +export const VALID_EDGES: Array = [ + EDGE_TYPE_INFO_CONSUME_DATA, + EDGE_TYPE_INFO_CONSUME_EVENT, + EDGE_TYPE_INFO_CONSUME_PATH, + EDGE_TYPE_INFO_IS_SUB_INFO, + EDGE_TYPE_LOGIC_AVOIDS, + EDGE_TYPE_LOGIC_CONSUME_TOKEN, + EDGE_TYPE_LOGIC_PRODUCE_TOKEN, + EDGE_TYPE_LOGIC_RELEASES, + EDGE_TYPE_LOGIC_REMOVE_RELEASES, + EDGE_TYPE_LOGIC_REQUIRES, + EDGE_TYPE_LOGIC_TRIGGERS, + EDGE_TYPE_PLANNER_AVOIDS, + EDGE_TYPE_PLANNER_LEADS_TO, + EDGE_TYPE_PLANNER_RELEASES, + EDGE_TYPE_PLANNER_REQUIRES, +]; + +export interface IBaseEdge { + from: string; + to: string; + category: VALID_EDGES; +} + +export interface PE extends Partial {} diff --git a/lib/types/ui/editor/IEditPage.ts b/lib/types/ui/editor/IEditPage.ts new file mode 100644 index 0000000..fde4804 --- /dev/null +++ b/lib/types/ui/editor/IEditPage.ts @@ -0,0 +1,37 @@ +import { TRenderFunctionResult } from "../layout.interface"; +import { IPort } from "./INodes"; + +export interface IEditPage extends TRenderFunctionResult { + /** + * Function, which must return the current data. + * + * @author M.Karkowski + * @return {boolean} + * @memberof IEditPage + */ + getData(): T; + + /** + * Function which must return true, if the Entered- + * Data is valid. Otherwise the Update will be refused + * + * @author M.Karkowski + * @return {boolean} + * @memberof IEditPage + */ + isValid(): boolean; + + /** + * Element showing the type of the edit panel. + */ + type: "node" | "edge"; + + /** + * Function to store the changed Edge data. + * @param options adapted Edge Options. + */ + getPorts(): { + inputs: IPort[]; + outputs: IPort[]; + }; +} diff --git a/lib/types/ui/editor/INetwork.ts b/lib/types/ui/editor/INetwork.ts new file mode 100644 index 0000000..e69de29 diff --git a/lib/types/ui/editor/INodes.ts b/lib/types/ui/editor/INodes.ts new file mode 100644 index 0000000..aaa8cdd --- /dev/null +++ b/lib/types/ui/editor/INodes.ts @@ -0,0 +1,109 @@ +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + * @desc [description] + */ + +export type PORT_AVOID_TOKEN = "flow.input.avoid"; +export type PORT_CONSUME_TOKEN = "flow.input.consume"; +export type PORT_DATA = "dataPort"; +export type PORT_EVENT = "eventPort"; +export type PORT_LOGIC_FLOW = "logicFlowPort"; +export type PORT_PLACE = "flow.place"; +export type PORT_PRODUCE_TOKEN = "flow.output.produce"; +export type PORT_REQUIRE_TOKEN = "flow.input.require"; +export type VALID_PORTS = + | PORT_AVOID_TOKEN + | PORT_CONSUME_TOKEN + | PORT_DATA + | PORT_EVENT + | PORT_LOGIC_FLOW + | PORT_PLACE + | PORT_PRODUCE_TOKEN + | PORT_REQUIRE_TOKEN; + +export type NODE_TYPE_COMPOSED = "node:composed"; +export type NODE_TYPE_CONSTANT = "data:constant"; +export type NODE_TYPE_DATA_TO_TOKEN = "logic:data-to-token"; +export type NODE_TYPE_FLOW_OPERATION = "logic:flow"; +export type NODE_TYPE_PLACE = "logic:place"; +export type NODE_TYPE_TOKEN_TO_DATA = "logic:token-to-data"; +export type NODE_TYPE_TRANSITION = "logic:transition"; +export type NODE_TYPE_VAR = "data:constant"; + +export type VALID_NODES = + | NODE_TYPE_COMPOSED + | NODE_TYPE_CONSTANT + | NODE_TYPE_DATA_TO_TOKEN + | NODE_TYPE_FLOW_OPERATION + | NODE_TYPE_PLACE + | NODE_TYPE_TOKEN_TO_DATA + | NODE_TYPE_TRANSITION + | NODE_TYPE_VAR + | VALID_PORTS; + +export const PORT_AVOID_TOKEN: PORT_AVOID_TOKEN = "flow.input.avoid"; +export const PORT_CONSUME_TOKEN: PORT_CONSUME_TOKEN = "flow.input.consume"; +export const PORT_DATA: PORT_DATA = "dataPort"; +export const PORT_EVENT: PORT_EVENT = "eventPort"; +export const PORT_LOGIC_FLOW: PORT_LOGIC_FLOW = "logicFlowPort"; +export const PORT_PLACE: PORT_PLACE = "flow.place"; +export const PORT_PRODUCE_TOKEN: PORT_PRODUCE_TOKEN = "flow.output.produce"; +export const PORT_REQUIRE_TOKEN: PORT_REQUIRE_TOKEN = "flow.input.require"; + +export const VALID_PORTS: Array = [ + PORT_AVOID_TOKEN, + PORT_CONSUME_TOKEN, + PORT_DATA, + PORT_EVENT, + PORT_LOGIC_FLOW, + PORT_PLACE, + PORT_PRODUCE_TOKEN, + PORT_REQUIRE_TOKEN, +]; + +export const NODE_TYPE_COMPOSED: NODE_TYPE_COMPOSED = "node:composed"; +export const NODE_TYPE_CONSTANT: NODE_TYPE_CONSTANT = "data:constant"; +export const NODE_TYPE_DATA_TO_TOKEN: NODE_TYPE_DATA_TO_TOKEN = + "logic:data-to-token"; +export const NODE_TYPE_FLOW_OPERATION: NODE_TYPE_FLOW_OPERATION = "logic:flow"; +export const NODE_TYPE_PLACE: NODE_TYPE_PLACE = "logic:place"; +export const NODE_TYPE_TOKEN_TO_DATA: NODE_TYPE_TOKEN_TO_DATA = + "logic:token-to-data"; +export const NODE_TYPE_TRANSITION: NODE_TYPE_TRANSITION = "logic:transition"; +export const NODE_TYPE_VAR: NODE_TYPE_VAR = "data:constant"; + +export const VALID_NODES: Array = [ + NODE_TYPE_COMPOSED, + NODE_TYPE_CONSTANT, + NODE_TYPE_DATA_TO_TOKEN, + NODE_TYPE_FLOW_OPERATION, + NODE_TYPE_PLACE, + NODE_TYPE_TOKEN_TO_DATA, + NODE_TYPE_TRANSITION, + NODE_TYPE_VAR, +]; +VALID_PORTS.map((id) => VALID_NODES.push(id)); + +/** + * Information of a base node in a graph. + */ +export interface IBaseNode { + key: string; + location: { x: number; y: number }; + category: VALID_NODES; + size: { + width: number; + height: number; + }; +} + +export interface IPort { + label: string; + portId: string; + type: VALID_PORTS; + allowMultipleInputs?: true; + portColor?: string; +} + +export interface PN extends Partial {} diff --git a/lib/types/ui/editor/index.ts b/lib/types/ui/editor/index.ts new file mode 100644 index 0000000..2280971 --- /dev/null +++ b/lib/types/ui/editor/index.ts @@ -0,0 +1,18 @@ +/** + * @module editorUi + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +export * from "./IEdges"; +export * from "./IEditPage"; +export * from "./IEdges"; +// export * from "./INetwork"; +export * from "./INodes"; +export * from "./render.callbacks"; + +import * as nodes from "./INodes"; +import * as edges from "./IEdges"; +import * as callbacks from "./render.callbacks"; + +export { nodes, edges, callbacks }; diff --git a/lib/types/ui/editor/render.callbacks.ts b/lib/types/ui/editor/render.callbacks.ts new file mode 100644 index 0000000..6821210 --- /dev/null +++ b/lib/types/ui/editor/render.callbacks.ts @@ -0,0 +1,11 @@ +import { IRenderData } from "../helpers.interface"; +import { IEditPage } from "./IEditPage"; +import { PN } from "./INodes"; + +/** Helper to configurate a service */ +export type TRenderConfigureServicePage = ( + div: HTMLDivElement, + options: IRenderData & { + input: T; + } +) => IEditPage; diff --git a/lib/types/ui/helpers.interface.ts b/lib/types/ui/helpers.interface.ts new file mode 100644 index 0000000..ac607e8 --- /dev/null +++ b/lib/types/ui/helpers.interface.ts @@ -0,0 +1,393 @@ +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +import { ILogger } from "js-logger"; +import { IJsonSchema } from "../IJSONSchema"; +import { INopeDispatcher, INopeObservable } from "../nope/index"; +import * as nope from "../../index.browser"; +import * as plotly from "plotly.js"; +import * as go from "gojs"; +import { + IPanel, + IPossiblePanels, + IMinProvidedDataSet, + IRadioMenuItemDescription, +} from "./layout.interface"; + +export type TSettingsObject = { [index: string]: string | number | boolean }; + +/** Descripting a session, which the ui has established. */ +export type TSession = { + name: string; + uri: string; + port: number; + connection: "mqtt" | "io-client"; + forwardData: boolean; + required: boolean; +}; + +/** A Schema to receive an object from the url (use the query pattern) */ +export type TSimpleSchema = { + [index: string]: + | "number" + | "integer" + | "string" + | "boolean" + | { + parse: (data: string) => any; + validate: (data: string) => boolean; + }; +}; + +/** + * Type containing the external libraries. + */ +export type TLibraries = { + /** + * The Nope Library. It contains only the Browser build. + * + * @type {typeof nope} + */ + nope: typeof nope; + + /** + * Built on top of d3.js and stack.gl, Plotly.js is a high-level, declarative charting library. plotly.js ships with over 40 chart types, including 3D charts, + * statistical graphs, and SVG maps. plotly.js is free and open source and you can view the source, report issues or contribute on GitHub. + * + * For Tutorials and more checkout: https://plotly.com/javascript/ + */ + plotly: typeof plotly; + + /** + * Out of the box w2ui is an all-in-one solution. It contains common UI widgets: Grid, Forms, Toolbars, Layout, Sidebar, Tabs, Popup and various field controls. + * You do not need to put together a collection of mismatched plugins to accomplish your goals. + * + * Contains the original w2ui Library. https://w2ui.com/web/ + */ + w2ui: any; + + /** + * jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, + * animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, + * jQuery has changed the way that millions of people write JavaScript. + * + * Contains jQuery. See: https://jquery.com/ + */ + jQuery: any; + + /** + * Contains a library for a dynamic JSON-Editor. This contains a tree-view, with edit options. + * + * For more details checkout: https://github.com/josdejong/jsoneditor + */ + jsoneditor: any; + + /** + * GoJS is a JavaScript library that lets you easily create interactive diagrams in modern web browsers. GoJS supports graphical templates and data-binding + * of graphical object properties to model data. You only need to save and restore the model, consisting of simple JavaScript objects holding whatever properties + * your app needs. Many predefined tools and commands implement the standard behaviors that most diagrams need. Customization of appearance and behavior is + * mostly a matter of setting properties. + * + * For more details checkout: https://gojs.net/latest/ + */ + gojs: typeof go; +}; + +export type TcreateLayoutOptions = { + /** + * Id of the Layout + */ + id: string; + /** + * ID of the div. given via `
` + */ + divId: string; + /** + * Function which is called during resizing. + * + * Receives the `event` and the `panels` (containg all panels of the layout) + */ + onResizeCallback?: (event: any, panels?: IPossiblePanels) => void; + /** + * The width, that should be set e.g. `100%` or `100px` + */ + width?: string | number; + /** + * The height, that should be set e.g. `100%` or `100px` + */ + height?: string | number; + + /** + * To define. + * + * @type {*} + */ + colors?: any; +}; + +/** Helper for the provided data: */ +export interface IRenderData { + helpers: { + data: { + /* + * Function to set a data element. usally stores the data in key <-> value combination. + * Make shure we are able to parse the data (for instance to json), before using this function. + * + * @param {string} key The key to store the value. + * @param {*} value The data that should be stored. + * @return {Promise} + * @memberof IDataInterface + */ + setData(key: string, value: any): Promise; + + /** + * Helper to get the a value from the store, which is related to the key. If the data isn't present, + * the store **must** store the provided `defaultValue`. Afterwards it **must** return the provided + * `defaultValue` + * + * @template T expected type. Is defined by the `defaultValue` + * @param {string} key The key, under which the data is expected. + * @param {T} defaultValue The default value, which should be used if the data isnt present. + * @return {Promise} The extracted data / `defaultValue` + * @memberof IDataInterface + */ + getData(key: string, defaultValue: T): Promise; + }; + connection: { + /** + * Flag showing whether the Service is connected to a backend or not + * + * @type {INopeObservable} + * @memberof INoPEConnectService + */ + sessionsConnected: INopeObservable; + /** + * Flag, to define, whether a external connection is required to + * set the {@link INoPEConnectService.sessionsConnected} to true. + * + * @type {boolean} + * @memberof INoPEConnectService + */ + noExternalConnectionRequired: boolean; + /** + * Helper Function to establish a connection to a backend. If called, to url is changed to the `pages/connect` and after a sucessfull connection, the original url is loaded **again**. + * + * >Use with care, if you get problems reloading the side again. + * @param options + * @returns + */ + connect(options?: { + delay: number; // Delay, after which the page is reloaded. + }): Promise; + }; + file: { + /** + * Helper to upload data to the browser. (Opens a Popup) + * + * > The data is only available in the Browser. + */ + upload: (options: { + /** + * Title of the upload form + */ + title: string; + width?: number; + height?: number; + /** + * Callback which is called after the data has been received. + * + * @param error Error, during uploading + * @param data The data formated as **string** + */ + callback(error: any, data: string): void; + }) => void; + /** + * Downloads some content as file. + * + */ + download: ( + content: string, + fileName?: string, + option?: { + /** + * Automatically provide Unicode text encoding hints + * @default false + */ + autoBom: boolean; + } + ) => void; + }; + info: { + hostname: string; + /** + * Returns the available layers. + * + * @author M.Karkowski + * @readonly + * @type {(Array)} + * @memberof NoPEService + */ + readonly layers: Array; + /** + * Adds an communication Layer. + * + * @param {TSession} _session The Parameters for the Session. + * @memberof NoPEService + */ + addCommunicationLayer(_session: TSession): void; + + /** + * Disconnects the Layer. + * @param session The Session Parameters to use. + */ + removeCommunicationLayer(session: TSession): void; + }; + url: { + /** + * Helper to get an Object from a schema. The Schema must be from type Object and is only allowed to have + * types "number", "boolean", "integer", "string". If a different type is used an error is thrown. + * @param schema The JSON-Schema + * @returns + */ + getObjectFromQueryWithSchema( + schema: IJsonSchema + ): Promise<{ [index: string]: any } | false>; + + /** + * Extract the data based on some query parameters. The Parameters to use are provided in the schema object. + * @param simpleSchema + * @returns + */ + getObjectFromQuery( + simpleSchema: TSimpleSchema + ): Promise<{ [index: string]: any } | false>; + + /** + * Generates a link with Query Parameters. + * @param object + * @returns + */ + generateLinkWithQueryParams( + ...objects: TSettingsObject[] + ): Promise; + }; + layout: { + /** + * Helper to create a W2UI Layout + * + * @param {IPanel[]} panelConfig + * @param {TcreateLayoutOptions} options + * @param {...any[]} args + * @return {*} + */ + createLayout( + panelConfig: IPanel[], + options: TcreateLayoutOptions, + ...args: any[] + ): { + layout: { + layout: any; + element: any; + destroy: () => void; + }; + panels: IPossiblePanels; + }; + toolbar: { + /** + * Helper function, to generate a Radio Menu Entry for a Toolbar. + * + * @export + * @template D The desired callback Data. + * @template T The desired data of the item. + * @param options The Options to define the radio-menu. Must contain items and a onSelect callback. + * @return {*} + */ + generateRadioMenuEntry< + D extends IMinProvidedDataSet = IMinProvidedDataSet, + T extends IRadioMenuItemDescription = IRadioMenuItemDescription + >(options: { + /** + * The Toolbar Entries. + * + * @type {T[]} + */ + items: T[]; + /** + * The Id of the already selected radio-element + * + * @type {string} + */ + selected?: string; + /** + * Callback, that should be called on selecting a radio-box item. + * + */ + onSelect: (data: D, item: T) => void; + }): void; + + /** + * Helper to render a Select Toobar. + * + * @template D + * @template T + * @param options + */ + generateSelectMenuEntry< + D extends IMinProvidedDataSet, + T extends IRadioMenuItemDescription + >(options: { + /** + * The Items which can be selected + */ + items: (T | string)[]; + /** + * The Selected Item + */ + selected?: string; + /** + * The Text to Show + */ + text: string; + onSelect: (data: D, selection: { [index: string]: boolean }) => void; + }): void; + }; + }; + }; + logger: ILogger; + dispatcher: INopeDispatcher; + libraries: TLibraries; +} + +/** Helper used, to render the instance details */ +// export type TRenderInstancePage = ( +// div: HTMLDivElement, +// options: TRenderData & { +// input: T; +// } +// ) => TRenderFunctionResult; + +// /** Helper to configurate a service */ +// export type TRenderConfigureServicePage = ( +// div: HTMLDivElement, +// options: TRenderData & { +// input: T; +// } +// ) => IEditPage; + +// /** UI to define an instance. */ +// export type TCreatorPage = ( +// div: HTMLDivElement, +// options: TRenderData & { +// createInstance: T; + +// } +// ) => IEditPage; + +// export type TRenderEditPage = ( +// div: HTMLDivElement, +// options: TRenderData & { +// input: T; +// } +// ) => IEditPage; diff --git a/lib/types/ui/index.ts b/lib/types/ui/index.ts new file mode 100644 index 0000000..ca1eb09 --- /dev/null +++ b/lib/types/ui/index.ts @@ -0,0 +1,13 @@ +/** + * @module ui + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +import * as editor from "./editor/index"; +import * as layout from "./layout.interface"; + +export { TCreatorPage, TRenderInstancePage } from "./render.callbacks"; +export { TRenderConfigureServicePage } from "./editor/index"; + +export { editor, layout }; diff --git a/lib/types/ui/layout.interface.ts b/lib/types/ui/layout.interface.ts new file mode 100644 index 0000000..6619521 --- /dev/null +++ b/lib/types/ui/layout.interface.ts @@ -0,0 +1,1145 @@ +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +import { INopeEventEmitter } from "../nope/nopeEventEmitter.interface"; +import { INopeObservable } from "../nope/nopeObservable.interface"; + +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + * @desc [description] + */ + +export interface IMinProvidedDataSet { + event: any; + panels: IPossiblePanels; +} + +export type ICallback = (data: D) => void; + +/** Default Callback for Buttons etc inside of a toolbar and the layout. */ +export type IAdaptDataCallback = ( + event: any, + panels: IPossiblePanels +) => D; + +/** Valid panel defintions. (see w2ui) */ +export type ValidPanels = + | "left" + | "right" + | "top" + | "bottom" + | "preview" + | "main"; + +export const ValidPanels: ValidPanels[] = [ + "left", + "right", + "top", + "bottom", + "preview", + "main", +]; + +export type IPossiblePanels = { + [P in ValidPanels]?: IPanelInstance; +}; + +export type IPanels = { + [P in ValidPanels]?: IPanelControl; +}; + +export interface IPanelControl { + visible: boolean; + toggle(): void; + icon: + | "arrow-left-outline" + | "arrow-right-outline" + | "arrow-up-outline" + | "arrow-down-outline" + | string; + tooltip: string; + enabled: boolean; +} + +/** + * Base data of an W2UI-Element + * + * @export + * @interface IBaseElement + * @template D The desired data, which will be used during callbacks. + */ +export interface IBaseElement { + /** + * Id of the Element + * + * @type {string} + */ + id: string; + /** + * Flag to disable the Element + * + * @type {boolean} + */ + disabled?: boolean; + /** + * Flag to hide the element. + * + * @type {boolean} + */ + hidden?: boolean; + /** + * Text to render + */ + text?: string | ((item: any) => string); + /** + * Style sheet + */ + style?: string; + /** + * Badge to be rendered as counter (number) + */ + count?: number; + /** + * The Type. This will be overwritten by the elements. + * + * @type {string} + */ + type?: string; + /** + * A Tooltip, which will be renderd on hovering. + * + * @type {string} + */ + tooltip?: string; + /** + * Callback which will be called, on clicking the element + */ + onClick?: ICallback; + /** + * Callback which will be called, on refresing (rerendering) the element + */ + onRefresh?: ICallback; +} + +/** A Classical Button */ +export interface IButton + extends IBaseElement { + type: "button"; + /** An Icon, which will be rendered next to the Label of the button */ + icon?: string; + /** An Image, which will be rendered next to the Label */ + img?: string; +} + +/** A Classical Checkbox */ +export interface ICheckbox + extends IBaseElement { + type: "check"; + /** An Icon, which will be rendered next to the Label */ + icon?: string; + /** An Image, which will be rendered next to the Label */ + img?: string; + /** An Flag, which will set the Element to Checked or not */ + checked?: boolean; +} + +/** A Classical Radiobutton */ +export interface IRadioButton + extends IBaseElement { + type: "radio"; + /** An Icon, which will be rendered next to the Label */ + icon?: string; + /** An Image, which will be rendered next to the Label */ + img?: string; + /** Flag, whether this element will be checked or not */ + checked?: boolean; + /** + * Group of the Radio-Buttons. A Group contains multiple + * Element. But in a group, only one element can be selected + * at the same time + */ + group?: string | number; +} + +/** + * Helper Entry for a Radio Menu Entry + * + * @export + * @interface IRadioMenuItemDescription + */ +export interface IRadioMenuItemDescription { + id: string; + /** + * Text of the Radio element. It will usally be render next to the icon + * + * @type {string} + * @memberof IRadioMenuItemDescription + */ + text?: string; + /** + * An icon, which will be rendered. + * + * @type {string} + * @memberof IRadioMenuItemDescription + */ + icon?: string; + /** + * An image instead of the icon. + * + * @type {string} + * @memberof IRadioMenuItemDescription + */ + img?: string; + /** + * Option, to disable the entry. + * + * @type {boolean} + * @memberof IRadioMenuItemDescription + */ + disabled?: boolean; + + checked?: boolean; + selected?: boolean; +} + +/** + * An Element containing a Menu wiht Buttons + */ +export interface IMenu extends IBaseElement { + type: "menu"; + /** valid Icons next to the Menu */ + icon?: + | "icon-folder" + | "icon-page" + | "icon-reload" + | "icon-columns" + | "icon-search" + | "icon-add" + | "icon-delete" + | "icon-save" + | "icon-edit" + | "icon-bullet-black"; + /** + * List of Items, which will be rendered in the Menu + */ + items: Array | IMenu>; +} + +/** + * A Sub-Menu containing checkable Attributes + */ +export interface IMenuCheckbox + extends IBaseElement { + type: "menu-check" | "menu-radio"; + icon?: + | "icon-folder" + | "icon-page" + | "icon-reload" + | "icon-columns" + | "icon-search" + | "icon-add" + | "icon-delete" + | "icon-save" + | "icon-edit" + | "icon-bullet-black"; + items: Array<{ + id: string; // id of the menu item + text?: string; // text of the menu item + icon?: string; // css class for icon font + img?: string; // css class for an image + disabled?: boolean; // indicates if menu item is disabled + checked?: boolean; // indicates if menu item is checked (for menu-check or menu-radio) + selected?: boolean; + }>; + selected?: string; +} + +/** + * A customizable dropdown + */ +export interface ICustomDropDown + extends IBaseElement { + type: "drop"; + /** + * A text (containing the HTML Code), or a function, which will + * return the HTML code. + */ + html: string | ((value: any) => string); +} + +/** + * A customizable HTML element in the Menu + */ +export interface ICustomHTML + extends IBaseElement { + type: "html"; + /** + * A text (containing the HTML Code), or a function, which will + * return the HTML code. + */ + html: string | ((value: any) => string); +} + +/** + * A Color Picker + */ +export interface IColor extends IBaseElement { + type: "color"; + /** + * Parameter to disable/activate transparent Colors + */ + transparent?: boolean; +} + +/** + * A Color selector, which uses a Textinput to render the Hex-Code + */ +export interface ITextColor + extends IBaseElement { + type: "text-color"; + /** + * Parameter to disable/activate transparent Colors + */ + transparent?: boolean; +} + +/** + * A Simple Break (a vertical line) + */ +export interface IBreak { + type: "break"; +} + +/** + * Simple Spacer + */ +export interface ISpacer { + type: "spacer"; +} + +/** + * Type describing valid Elements of A Menu + */ +export type IToolbarElements = + | IButton + | ICheckbox + | IRadioButton + | IMenu + | IMenuCheckbox + | ICustomDropDown + | ICustomHTML + | IColor + | ITextColor + | IBreak + | ISpacer; + +/** + * A Menu + */ +export interface IMenubar { + /** + * Elements, ordered by their index, which should be + * rendered in the Menu. + */ + items: Array>; +} + +/** + * A Configuration to define a Tab-Group + * + * @export + * @interface ITabProps + */ +export interface ITabProps { + /** + * Callback, which will be call during rendering the tab group for the first time. + * + * @memberof ITabProps + */ + onMount?: (item: ITabProps) => void; + + /** + * Callback, which will be called if a new tab is created. If creating is permitted, + * the promise must resolve `false`, otherwise a tab-defintion (see {@link ITab}) must + * be resolved. + * + * @memberof ITabProps + */ + onNewTab?: () => Promise; + + /** + * Callback, which is call if the user wants to change the tab. The callback must resolve + * a `boolean`, where as `true` allows the tab-change, `false` permits the change. + * + * @memberof ITabProps + */ + onTabSelect?: (oldTabId: ITab, newTabId: ITab) => Promise; + + /** + * Callback, which is called, if the Tab receivs a `double-click`. The function can adapt + * the Tab configuration (for example its label) which must be returned by this label. + * + * @memberof ITabProps + */ + onTabEdit?: (tab: ITab) => Promise; + + /** + * Callback, which is call if the user wants to change the tab. The callback must resolve + * a `boolean`, where as `true` allows the deleting the tab, `false` permits deleting the + * tab. + * + * @memberof ITabProps + */ + onTabDelete?: (tabId: ITab, forced?: boolean) => Promise; + + /** + * A callback, which will be called, if all tabs has been closed. + * + * @memberof ITabProps + */ + onNoTabSelected?: () => Promise; + + /** + * Callback, which is called if the Configuration has been changed. This is the case, if a + * tab as been `added`, `selected` or `removed` + * + * @memberof ITabProps + */ + onConfigChanged?: (config: ITabProps) => void; + /** + * Flag to allow / disable reordering of the tabs. + * + * @type {boolean} + * @memberof ITabProps + */ + reorder?: boolean; + + /** + * Object, containing the inital tabs. + * + * @memberof ITabProps + */ + tabs: { + /** + * Flag, which will ensure that there exits a tab + * with the label `+`. If clicked, a new tab will + * be inserted. This results in the calling the + * {@link ITabProps.onNewTab} callback. + * + * @type {boolean} + */ + allowNewTabs?: boolean; + /** + * Flag of the active tab. + * + * @type {string} + */ + active: string; + /** + * List of the available tabs. + * + * @type {ITab[]} + */ + items: ITab[]; + }; + // Name of the Tab-Group. + name: string; + /** + * The id of the W2UI-Layout, where the tab-group is getting rendered + * + * @type {string} + * @memberof ITabProps + */ + layoutId: string; + /** + * The position on the W2UI-Layout, where the tab-group is getting rendered + * + * @type {ValidPanels} + * @memberof ITabProps + */ + position: ValidPanels; +} + +export type TRenderAngularComponentAtElement = (options: { + element: any; + component: T; + inputs?: { [index: string]: any }; + outputs?: { [index: string]: (value: any) => void }; +}) => { + destroy: () => void; + instance: T; +}; + +export interface IPanelOptions { + // The Panel ID + id: string; + // type of the panel can be: left, right, top, bottom, preview + type: ValidPanels; + // title for the panel + title?: string; + // width or height of the panel depending on panel type + size?: number; + // minimum size of the panel in px when it is resized + minSize?: number; + // if a number, then it defined maximum size of the panel + maxSize?: number; + // indicates if panel is hidden + hidden?: boolean; + // indicates if panel is resizable + resizable?: boolean; + // overflow property of the panel, can have same values as similar CSS property + overflow?: string; + // additional css styles for the panel + style?: string; + // content of the pane, can be a string or an object with .render(box) method + content?: string | any; + // width of the panel, read only + width?: number; + // height of the panel, read only + height?: number; + // w2tabs object for the panel + tabs?: Partial; + + // The Rendering Settings. + rendering?: TRendering; + + show?: { + // indicates what sections are shown + tabs: boolean; + toolbar: boolean; + }; +} + +export interface IPanel extends IPanelOptions { + id: string; + + // toolbar?: IToolbar, + /** + * Enable / Disable the Toggle Button on the bottom. Defaults to false. + */ + toggle?: + | boolean + | { + /** + * Provide an additional Tool-Tip. + */ + tooltip: + | { + show: string; + hide: string; + } + | string; + /** + * Custom Icon to use. + */ + icon: + | { + show: string; + hide: string; + } + | string; + }; + /** + * Style for the Panel + */ + style?: string; + // events + onRefresh?: (event: any) => void; // refresh event for the panel + onResizing?: (event: any) => void; // resizing event for the panel + onShow?: (event: any) => void; // show event for the panel + onHide?: (event: any) => void; // hide event for the panel + callback?: (event: any) => void; +} + +export interface ITab { + id: string; // command to be sent to all event handlers + text: string; // tab caption + hidden?: boolean; // defines if tab is hidden + disabled?: boolean; // defines if tab is disabled + closable?: boolean; // defines if tab is closable + style?: string; // additional style for the tab text + tooltip?: string; // mouse hint for the tab + onClick?: (event: any) => void; // click event handler (only this tab) + onRefresh?: (event: any) => void; // refresh event handler (only this tab) + onClose?: (event: any) => void; // close event handler (only this tab), + rendering?: TRendering; +} + +export type TRendering = + | IRenderHTML + | IRenderW2UIElement + | IRenderMarkdown + | ICustomRender; + +export interface IRenderHTML { + type: "html"; + html: string; +} + +export interface IRenderMarkdown { + type: "markdown"; + markdown: string; +} + +export interface ICustomRender { + type: "custom"; + create: (div: HTMLElement) => Promise; + destroy: () => Promise; +} + +export interface IRenderW2UIElement { + type: "w2ui-element"; + elementID: string; +} + +export interface IToolbar { + items: Array>; +} + +export interface ISelectionContextMenuEntry { + id: string; + text: string; + icon?: string; + hidden?: boolean; + callback?: (menu: ISelectionContextMenuEntry[], item: T) => void; +} + +export interface IAdditionalSelectionContextMenuEntry + extends ISelectionContextMenuEntry { + callback: (menu: ISelectionContextMenuEntry[], item: T) => void; +} + +/** + * An Interface to define a Windows-Like-Toolbar. + */ +export interface IToolbarConfig { + // Element to Select an Active Tab + activeTab?: string; + // Object containing the Tabs with the Corresponding Menu + tabs: { + [index: string]: { + /** + * The Render Text of the Tab + */ + text: string; + /** + * Flag which hides the Toolbar + */ + hidden?: boolean; + /** + * Flag which disables the Toolbar + */ + disabled?: boolean; + /** + * A Tooltip, which is shown on hovering over the Tab-Element + */ + tooltip?: string; + /** + * A Configuration of the Menu, which is provided inside of the Toolbar. + */ + menu: IMenubar; + }; + }; +} + +export interface ILayout { + // The size of draggable resizer between panels. + resizer?: number; + + // Padding between panels in px. + padding?: number; + + // The Included Panels + panels?: IPanel[]; +} + +export interface IPanelInstance { + // The Panel Object + panel: any; + // The Element + element: HTMLElement; + // A Function to Destroy the Panel + destroy(): void; + // Hide the Panel + hide(immediate?: boolean): void; + // Show the Panel + show(immediate?: boolean): void; + // Resize the Panel to the desired Size + resize(size: number): void; + // Function to Show a Message + showMessage(options: { + html?: string; // html of the message + body?: string; // similar to body in w2popup, can be used instead of options.html + buttons?: string; // similar to buttons in w2popup, can be used instead of options.html + width?: number; // width in px (if negative, then it is 100% of popup in message.width) + height?: number; // height in px (if negative, then it is 100% of popup in message.height) + hideOnClick?: boolean; // if true, hide message if user clicks on it + onOpen?: (event: any) => void; // function to execute when message opens + onClose?: (event: any) => void; // function to execute when message closes + }): void; + // Function to Close the Message + closeMessage(): void; + width(): number; + height(): number; + options: IPanelOptions; +} + +/** + * A Interface for a Group + */ +export interface ISelectionGroup { + /** A Flag, for showing, that the Element is a Group */ + group: true; + /** The Label / Text of the Group, if it is rendered in the Sidebar */ + text: string; + /** The Elements, which are provided in the Group */ + elements: Array | ISelectionGroup>; +} + +/** + * A Template for an element in the Sidebar + */ +export interface ISelectionTemplate { + /** The Label / Text of the Group, if it is rendered in the Sidebar */ + text: string; + /** A List of Keywords, which are used to Find the corresponding Elements */ + keywords: Array; + /** The Element containing the Template of a Node */ + template: T; + /** The Icon to use */ + icon?: string; +} + +/** + * The complete Config of the Selection interface + */ +export interface ISelectionConfig { + favorites: Array>; + elements: { + [index: string]: { + id: string; + label: string; + items: Array | ISelectionGroup>; + }; + }; +} + +/** + * The Element, which is rendered in the Selection + * + * (The ID is required by the W2UI) + */ +export interface ISelectionElement extends ISelectionTemplate { + id: number; +} + +export interface IW2UISelection { + id: string; + text: string; + expanded: boolean; + group: boolean; + groupShowHide: boolean; + hidden: boolean; + nodes: ISelectionElement[]; +} + +export interface IHotKeyAction { + /** + * The Pressed Key. Please use a valid "KeyCode". + * + * @type {string} + */ + keyCode: string; + /** + * Optional CTRL Key, which has to be pressed + * + * @author M.Karkowski + * @type {boolean} + * @memberof IHotKeyAction + */ + ctrlKey?: boolean; + /** + * Optional ALT Key, which has to be pressed + * + * @author M.Karkowski + * @type {boolean} + * @memberof IHotKeyAction + */ + altKey?: boolean; + /** + * Optional SHIFT Key, which has to be pressed + * + * @author M.Karkowski + * @type {boolean} + * @memberof IHotKeyAction + */ + shiftKey?: boolean; + /** + * The corresponding Callback, which will handle the + * Action if a Hotkey Press has been detected. + * + * @type {ICallback} + */ + onPress: ICallback; + /** + * The corresponding Callback, which will handle the + * Action if a Hotkey Press has been detected. + * + * @type {ICallback} + */ + onRelease?: ICallback; +} + +/** + * Options for a Layout + * + * @export + * @interface ILayoutOptions + * @template T The Template Element. + * @template D Callback Data + */ +export interface ILayoutOptions { + /** + * Define a custom ID. + */ + id?: string; + + /** + * The Title which will be shown on the Top. + * If not present, no titlebar will be shown + * + * @type {string} + * @memberof ILayoutOptions + */ + title: string; + + /** + * Helper to show the Toggle Elements or not. + */ + showToggleElements?: boolean; + + /** + * Configuration of the Toolbar. + * + * @type {{ + * config: IToolbarConfig + * panel: ValidPanels + * }} + * @memberof ILayoutOptions + */ + toolbar?: { + /** + * A Toolbar Configuration. + * + * @type {IToolbarConfig} + */ + config: IToolbarConfig; + + /** + * The Panel, which will be used to render the Toolbar. Normally this should be + * set to "top". + * + * @type {ValidPanels} + */ + panel: ValidPanels; + }; + + /** + * A List containing all Panels, which should be generaged + * + * @type {IPanel[]} + * @memberof ILayoutOptions + */ + panels: IPanel[]; + + /** + * Optional callback which will be called it a resize event occours. + * + * @memberof ILayoutOptions + */ + onResized?: (panels: IPossiblePanels) => void; + + /** + * Callback, which will be used to provide the actual Editmode. + * + * @memberof ILayoutOptions + */ + onEditModeChanged?: (editingEnabled: boolean) => void; + + /** + * Function, which will be called before the Componented is getting destroyed. + * This function could be used to clean up everything + * + * @memberof ILayoutOptions + */ + dispose?: () => void; + + /** + * An addtional Function which will be called before a Callback of the Context-Menu + * or Toolbar will be called. + * + * @type {IAdaptDataCallback} + * @memberof ILayoutOptions + */ + adaptData: IAdaptDataCallback; + + /** + * Optional Hotkey, which will triggerd custom Functions + * + * @type {{ + * key: string, + * onPress: ICallback + * }[]} + * @memberof ILayoutOptions + */ + hotkeys?: IHotKeyAction[]; + + /** + * Called if the layout is ready + * + * @author M.Karkowski + * @memberof ILayoutOptions + */ + onReady?: () => void; + + /** + * Boolean to toggle the FullScreen + * + * @author M.Karkowski + * @memberof ILayoutOptions + */ + fullScreen?: boolean; +} + +/** + * Type which is used to render an custom html code. + * Must return a function, which will be called if + * the panel is destroyed. + * + * Result, that must be provided by the Render Function. + */ +export type TRenderFunctionResult = { + /** + * Callback, which is called on destroyed + */ + onDestroy?: () => Promise; + /** + * Callback, which is called, if the panel is hide + */ + onHide?: () => Promise; + /** + * Callback, which is calle, if the Element is rendered. + */ + onShow?: () => Promise; +}; + +/** + * Type which is used to render an custom html code. + * Must return a function, which will be called if + * the panel is destroyed. + */ +export type TRenderFunction< + I, + O extends TRenderFunctionResult = TRenderFunctionResult, + D extends IMinProvidedDataSet = IMinProvidedDataSet, + A = any +> = ( + div: HTMLElement, + options: { + input: I; + setVisibilityOfPanel: (value: boolean) => void; + layout: IBasicLayoutComponent; + }, + args: A +) => O; + +/** + * Base Component to render a Layout. + */ +export interface IBasicLayoutComponent< + D extends IMinProvidedDataSet = IMinProvidedDataSet +> { + /** + * Flag, showing if the layout is ready or not. + * + * @type {INopeObservable} + * @memberof IBasicLayoutComponent + */ + ready: INopeObservable; + + /** + * An Eventemitter, to show that the system has been resized + * + * @type {INopeEventEmitter} + * @memberof IBasicLayoutComponent + */ + resized: INopeEventEmitter; + + /** + * The Elment, holding the currently created instances. + * + * @type {IPossiblePanels} + * @memberof IBasicLayoutComponent + */ + panels: IPossiblePanels; + + /** + * Controll elements for the Panels. Contains a toggle function, + * an icon, tooltip etc. This shows / hides the panels. + * + * @type {IPanelControl[]} + * @memberof IBasicLayoutComponent + */ + panelControlls: IPanelControl[]; + + /** + * + * + * @type {{ destroy(): void }} + * @memberof IBasicLayoutComponent + */ + toolbar: { destroy(): void }; + + /** + * The original W2UI Layout. See [here](https://w2ui.com/web/docs/2.0/) for more details and navigate to `layout`. + * There you'll find all methods, events and properties to manipulate the layout. But you should use the wrappers, + * provided by the abstraction in here. + * + * @type {*} + * @memberof IBasicLayoutComponent + */ + w2uiLayout: any; + + /** + * Element containing specific helpers. + * + * @author M.Karkowski + * @memberof IBasicLayoutComponent + */ + helpers: { [index: string]: (...args) => any }; + + /** + * Flag, to toggle the Panel-Control. If set to false this control is not shown. + * + * @type {boolean} + * @memberof IBasicLayoutComponent + */ + panelControlEnabled: boolean; + + /** + * Element to access the current Mouse-Position + * + * @type {MouseEvent} + * @memberof IBasicLayoutComponent + */ + currentMousePosition: MouseEvent; + + /** + * You can disable the hot-keys defined in configuration + * + * @type {boolean} + * @memberof IBasicLayoutComponent + */ + hotkeysEnabled: boolean; + + /** + * Helper, to check if the desired Panel is visible or not + * + * @param {ValidPanels} panel The panel to check. + * @return {boolean} + * @memberof IBasicLayoutComponent + */ + isPanelVisible(panel: ValidPanels): boolean; + + /** + * Function to toggle the visiblity of a given panel. + * + * @param {ValidPanels} panel The panel to manipulate. + * @param {boolean} visible The visibility. `false` => hidden; `true` => visible. + * @memberof IBasicLayoutComponent + */ + controllVisibilityOfPanel(panel: ValidPanels, visible: boolean): void; + + /** + * Helper to enable/disable the Controll Button of a panel. Therefore the Controll-Button + * must be present. + * + * @param {ValidPanels} panel The panel of the button to manipulate. + * @param {boolean} enabled `false` => disable; `true` => enable. + * @memberof IBasicLayoutComponent + */ + enablePanelControllButton(panel: ValidPanels, enabled: boolean): void; + + /** + * Toggles the Edit mode. + * + * @memberof IBasicLayoutComponent + */ + toggleEdit(): void; + + /** + * Opens a dynamic w2ui panel + * + * @author M.Karkowski + * @template I Input data + * @template A Additional Data + * @template O Result Function of the Function + * @param options The ptions + * @memberof IBasicLayoutComponent + */ + openDynamicW2UiPanel< + I = any, + A = any, + O extends TRenderFunctionResult = TRenderFunctionResult + >(options: { + /** Input which is fowarded to the render Function "render" */ + input?: I; + /** Callback which will be called to create the element */ + render: TRenderFunction; + /** Appends the Panel or replaces it. */ + append?: boolean; + /** Show the Panel on creating */ + showOnCreate?: boolean; + /** The Panel to show */ + panel: ValidPanels; + }): void; + + /** + * Returns the div of the panel. + * @param panel THe Panel. + */ + getElementOfPanel(panel: ValidPanels): null | any; + + /** + * Updates the content of the Panel. + * @param panel The panel + * @param content The content / HTML + */ + setContentOfPanel(panel: ValidPanels, content: string): void; + + /** + * Changes the visiblity of a panel + * + * @author M.Karkowski + * @param {ValidPanels} panel The panel to consider + * @param {boolean} show The Flag to show / hide the panel. VISIBLE = TRUE; + * @memberof IBasicLayoutComponent + */ + setVisibilityOfPanel(panel: ValidPanels, show: boolean): void; + + /** + * Helper to toggle the Screen mode (Fullscreen or normal) + * + * @author M.Karkowski + * @memberof IBasicLayoutComponent + */ + toggleScreenMode(): void; + + /** + * Contains an actual set of the current data. + */ + readonly data: D; +} diff --git a/lib/types/ui/render.callbacks.ts b/lib/types/ui/render.callbacks.ts new file mode 100644 index 0000000..119d88e --- /dev/null +++ b/lib/types/ui/render.callbacks.ts @@ -0,0 +1,34 @@ +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +import { IGenericNopeModule } from "../nope"; +import { IRenderData } from "./helpers.interface"; +import { TRenderFunctionResult } from "./layout.interface"; + +/** Helper used, to render the instance details */ +export type TRenderInstancePage< + T extends IGenericNopeModule = IGenericNopeModule +> = ( + /** The DIV Element */ + div: HTMLDivElement, + /** The Provided Options used by the function to create the ui */ + options: IRenderData & { + /** The Instance to Render. */ + input: T; + } +) => TRenderFunctionResult; + +/** UI to define an instance. */ +export type TCreatorPage = ( + /** The DIV Element */ + div: HTMLDivElement, + /** The Provided Options used by the function to create the ui */ + options: IRenderData & { + /** Name of the Constructor */ + ctorName: string; + /** The callback to create the instance. */ + createInstance: (...args) => Promise; + } +) => void; diff --git a/lib/ui/helpers.ts b/lib/ui/helpers.ts new file mode 100644 index 0000000..481e9f1 --- /dev/null +++ b/lib/ui/helpers.ts @@ -0,0 +1,23 @@ +/** + * @author Martin Karkowski + * @email m.karkowski@zema.de + */ + +import { stringifyWithFunctions } from "../helpers/index.browser"; +import { IGenericNopeModule, INopeModule } from "../module"; +import { TRenderInstancePage } from "../types/ui"; + +/** + * Converts the convertInstanceRenderPage to a string, which could be + * store or something similar. + * + * @export + * @template I The Instance Type + * @param {(TRenderInstancePage)} callback The callback to stringify. + * @return {string} The parsed String. + */ +export function convertInstanceRenderPage( + callback: TRenderInstancePage +): string { + return stringifyWithFunctions(callback); +} diff --git a/package-lock.json b/package-lock.json index aa7e056..95209d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "nope", - "version": "1.0.24", + "version": "1.0.35", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "nope", - "version": "1.0.24", + "version": "1.0.35", "license": "MIT", "dependencies": { "argparse": "^2.0.1", @@ -40,10 +40,12 @@ "nope-js": "bin/nope" }, "devDependencies": { + "@angular/core": "^14.0.3", "@types/async": "^3.2.12", "@types/chai": "^4.3.0", "@types/lodash": "^4.14.178", "@types/node": "^17.0.9", + "@types/plotly.js": "^1.54.22", "@types/socket.io": "^3.0.1", "@types/socket.io-client": "^1.4.36", "chai": "^4.3.4", @@ -53,6 +55,7 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.4", "eslint-plugin-prettier": "^4.0.0", + "gojs": "^2.2.11", "mocha": "^9.1.3", "npm-check-updates": "^12.1.0", "onchange": "^7.1.0", @@ -65,6 +68,22 @@ "webpack-cli": "^4.8.0" } }, + "node_modules/@angular/core": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.0.3.tgz", + "integrity": "sha512-Z71BrEIJuMGm/BdK9Lh8IJwADQqA8qPeUVppCs67CABZdwA3sK0kC+iobauWXcweXU30BdQYc7HyZe2x7rcdmQ==", + "dev": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.15.0 || >=16.10.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.11.4" + } + }, "node_modules/@babel/runtime": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", @@ -438,6 +457,12 @@ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" }, + "node_modules/@types/d3": { + "version": "3.5.47", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.47.tgz", + "integrity": "sha512-VkWIQoZXLFdcBGe5pdBKJmTU3fmpXvo/KV6ixvTzOMl1yJ2hbTXpfvsziag0kcaerPDwas2T0vxojwQG3YwivQ==", + "dev": true + }, "node_modules/@types/detect-indent": { "version": "0.1.30", "resolved": "https://registry.npmjs.org/@types/detect-indent/-/detect-indent-0.1.30.tgz", @@ -488,6 +513,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.9.tgz", "integrity": "sha512-5dNBXu/FOER+EXnyah7rn8xlNrfMOQb/qXnw4NQgLkCygKBKhdmF/CA5oXVOKZLBEahw8s2WP9LxIcN/oDDRgQ==" }, + "node_modules/@types/plotly.js": { + "version": "1.54.22", + "resolved": "https://registry.npmjs.org/@types/plotly.js/-/plotly.js-1.54.22.tgz", + "integrity": "sha512-/xL9++eA7VnIIZqNQOw6sZ7DtEmfoHj5rAD2CjU2LCOqem/BxTA1KlpdUWEHOiou6za4HKnM+Nvho3jTBPYJ/w==", + "dev": true, + "dependencies": { + "@types/d3": "^3" + } + }, "node_modules/@types/socket.io": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-3.0.2.tgz", @@ -4070,6 +4104,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gojs": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/gojs/-/gojs-2.2.11.tgz", + "integrity": "sha512-Zb6VucKWQhPlZCGUvuQFUb7X+VAfcapxYpAhta4Yq+ACwOpcNIL9ewjiACfW3nz2bkKK2qbahJBdzVwnKBsvZg==", + "dev": true + }, "node_modules/got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -15398,11 +15438,6 @@ "tslib": "^2.1.0" } }, - "node_modules/rxjs/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -16797,6 +16832,11 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -18249,9 +18289,28 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zone.js": { + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.6.tgz", + "integrity": "sha512-umJqFtKyZlPli669gB1gOrRE9hxUUGkZr7mo878z+NEBJZZixJkKeVYfnoLa7g25SseUDc92OZrMKKHySyJrFg==", + "dev": true, + "peer": true, + "dependencies": { + "tslib": "^2.3.0" + } } }, "dependencies": { + "@angular/core": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.0.3.tgz", + "integrity": "sha512-Z71BrEIJuMGm/BdK9Lh8IJwADQqA8qPeUVppCs67CABZdwA3sK0kC+iobauWXcweXU30BdQYc7HyZe2x7rcdmQ==", + "dev": true, + "requires": { + "tslib": "^2.3.0" + } + }, "@babel/runtime": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", @@ -18560,6 +18619,12 @@ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" }, + "@types/d3": { + "version": "3.5.47", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.47.tgz", + "integrity": "sha512-VkWIQoZXLFdcBGe5pdBKJmTU3fmpXvo/KV6ixvTzOMl1yJ2hbTXpfvsziag0kcaerPDwas2T0vxojwQG3YwivQ==", + "dev": true + }, "@types/detect-indent": { "version": "0.1.30", "resolved": "https://registry.npmjs.org/@types/detect-indent/-/detect-indent-0.1.30.tgz", @@ -18610,6 +18675,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.9.tgz", "integrity": "sha512-5dNBXu/FOER+EXnyah7rn8xlNrfMOQb/qXnw4NQgLkCygKBKhdmF/CA5oXVOKZLBEahw8s2WP9LxIcN/oDDRgQ==" }, + "@types/plotly.js": { + "version": "1.54.22", + "resolved": "https://registry.npmjs.org/@types/plotly.js/-/plotly.js-1.54.22.tgz", + "integrity": "sha512-/xL9++eA7VnIIZqNQOw6sZ7DtEmfoHj5rAD2CjU2LCOqem/BxTA1KlpdUWEHOiou6za4HKnM+Nvho3jTBPYJ/w==", + "dev": true, + "requires": { + "@types/d3": "^3" + } + }, "@types/socket.io": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-3.0.2.tgz", @@ -21519,6 +21593,12 @@ "slash": "^3.0.0" } }, + "gojs": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/gojs/-/gojs-2.2.11.tgz", + "integrity": "sha512-Zb6VucKWQhPlZCGUvuQFUb7X+VAfcapxYpAhta4Yq+ACwOpcNIL9ewjiACfW3nz2bkKK2qbahJBdzVwnKBsvZg==", + "dev": true + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -30064,13 +30144,6 @@ "integrity": "sha512-KExVEeZWxMZnZhUZtsJcFwz8IvPvgu4G2Z2QyqjZQzUGr32KDYuSxrEYO4w3tFFNbfLozcrKUTvTPi+E9ywJkQ==", "requires": { "tslib": "^2.1.0" - }, - "dependencies": { - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - } } }, "safe-buffer": { @@ -31198,6 +31271,11 @@ } } }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -32360,6 +32438,16 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zone.js": { + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.6.tgz", + "integrity": "sha512-umJqFtKyZlPli669gB1gOrRE9hxUUGkZr7mo878z+NEBJZZixJkKeVYfnoLa7g25SseUDc92OZrMKKHySyJrFg==", + "dev": true, + "peer": true, + "requires": { + "tslib": "^2.3.0" + } } } } diff --git a/package.json b/package.json index 7e25ea8..8abe346 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nope", - "version": "1.0.35", + "version": "1.1.00", "description": "NoPE Runtime for Nodejs. For Browser-Support please use nope-browser", "files": [ "dist-nodejs/**/*", @@ -71,6 +71,7 @@ "@types/chai": "^4.3.0", "@types/lodash": "^4.14.178", "@types/node": "^17.0.9", + "@types/plotly.js": "^1.54.22", "@types/socket.io": "^3.0.1", "@types/socket.io-client": "^1.4.36", "chai": "^4.3.4", @@ -80,6 +81,7 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.4", "eslint-plugin-prettier": "^4.0.0", + "gojs": "^2.2.11", "mocha": "^9.1.3", "npm-check-updates": "^12.1.0", "onchange": "^7.1.0", diff --git a/tsconfig.browser.json b/tsconfig.browser.json index f12bea8..e33396e 100644 --- a/tsconfig.browser.json +++ b/tsconfig.browser.json @@ -2,7 +2,8 @@ "compilerOptions": { "target": "ES2019", "lib": [ - "esnext" + "esnext", + "dom" ], "allowJs": true, "allowUnusedLabels": true, diff --git a/tsconfig.json b/tsconfig.json index 634a7ff..8b697c4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "target": "ES2019", "lib": [ - "esnext" + "esnext", + "dom" ], "allowJs": true, "allowUnusedLabels": true,