diff --git a/.storybook/addon-code/register.js b/.storybook/addon-code/register.js index b2ef16a..55a172d 100644 --- a/.storybook/addon-code/register.js +++ b/.storybook/addon-code/register.js @@ -50,7 +50,7 @@ export class CodePreview extends React.Component { {this.state.code} diff --git a/demos/.helpers/demo.scss b/demos/.helpers/demo.scss index e8f8a8c..4e1514d 100644 --- a/demos/.helpers/demo.scss +++ b/demos/.helpers/demo.scss @@ -1,80 +1,80 @@ @import "../../src/sass/main"; .srd-demo-workspace{ - background: black; - display: flex; - flex-direction: column; - height: 100%; - border-radius: 5px; - overflow: hidden; + background: black; + display: flex; + flex-direction: column; + height: 100%; + border-radius: 5px; + overflow: hidden; - &__toolbar{ - padding: 5px; - display: flex; - flex-shrink: 0; + &__toolbar{ + padding: 5px; + display: flex; + flex-shrink: 0; - button{ - background: rgb(60,60,60); - font-size: 14px; - padding: 5px 10px; - border: none; - color: white; - outline: none; - cursor: pointer; - margin: 2px; - border-radius: 3px; + button{ + background: rgb(60,60,60); + font-size: 14px; + padding: 5px 10px; + border: none; + color: white; + outline: none; + cursor: pointer; + margin: 2px; + border-radius: 3px; - &:hover{ - background: rgb(0,192,255); - } - } - } + &:hover{ + background: rgb(0,192,255); + } + } + } - &__content{ - flex-grow: 1; - height: 100%; - } + &__content{ + flex-grow: 1; + height: 100%; + } } .docs-preview-wrapper{ - background: rgb(60,60,60); - border-radius: 10px; - overflow: hidden; - padding: 10px; - margin-top: 20px; - margin-bottom: 20px; + background: rgb(60,60,60); + border-radius: 10px; + overflow: hidden; + padding: 10px; + margin-top: 20px; + margin-bottom: 20px; } .srd-demo-canvas{ - height: 100%; - min-height: 300px; - background-color: rgb(60,60,60) !important; - $color: rgba(white, .05); - background-image: - linear-gradient(0deg, - transparent 24%, - $color 25%, - $color 26%, - transparent 27%, - transparent 74%, - $color 75%, - $color 76%, - transparent 77%, - transparent), - linear-gradient(90deg, - transparent 24%, - $color 25%, - $color 26%, - transparent 27%, - transparent 74%, - $color 75%, - $color 76%, - transparent 77%, - transparent); - background-size:50px 50px; + height: 100%; + min-height: 300px; + background-color: rgb(60,60,60) !important; + $color: rgba(white, .05); + background-image: + linear-gradient(0deg, + transparent 24%, + $color 25%, + $color 26%, + transparent 27%, + transparent 74%, + $color 75%, + $color 76%, + transparent 77%, + transparent), + linear-gradient(90deg, + transparent 24%, + $color 25%, + $color 26%, + transparent 27%, + transparent 74%, + $color 75%, + $color 76%, + transparent 77%, + transparent); + background-size:50px 50px; - .pointui{ - fill: rgba(white,0.5); - } + .pointui{ + fill: rgba(white,0.5); + } } diff --git a/demos/demo-cloning/index.tsx b/demos/demo-cloning/index.tsx index 0c0dfc9..1e53898 100644 --- a/demos/demo-cloning/index.tsx +++ b/demos/demo-cloning/index.tsx @@ -15,7 +15,7 @@ import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget"; * Tests cloning */ class CloneSelected extends React.Component { - constructor(props) { + constructor(props: any) { super(props); this.cloneSelected = this.cloneSelected.bind(this); } diff --git a/demos/demo-custom-link1/index.tsx b/demos/demo-custom-link1/index.tsx index f0d7b86..dd67c38 100644 --- a/demos/demo-custom-link1/index.tsx +++ b/demos/demo-custom-link1/index.tsx @@ -11,7 +11,6 @@ import { } from "../../src/main"; import { action } from "@storybook/addon-actions"; import * as React from "react"; -import { LinkFactory } from "../../src/AbstractFactory"; import { DefaultLinkModel } from "../../src/defaults/models/DefaultLinkModel"; import { DefaultLinkFactory } from "../../src/defaults/factories/DefaultLinkFactory"; diff --git a/demos/demo-custom-node1/DiamondNodeFactory.tsx b/demos/demo-custom-node1/DiamondNodeFactory.tsx index cd5ffde..8048fdf 100644 --- a/demos/demo-custom-node1/DiamondNodeFactory.tsx +++ b/demos/demo-custom-node1/DiamondNodeFactory.tsx @@ -3,7 +3,7 @@ import { DiamonNodeWidget } from "./DiamondNodeWidget"; import { DiamondNodeModel } from "./DiamondNodeModel"; import * as React from "react"; -export class DiamondNodeFactory extends SRD.NodeFactory { +export class DiamondNodeFactory extends SRD.AbstractNodeFactory { constructor() { super("diamond"); } diff --git a/demos/demo-custom-node1/DiamondNodeWidget.tsx b/demos/demo-custom-node1/DiamondNodeWidget.tsx index cd4181f..c897ef0 100644 --- a/demos/demo-custom-node1/DiamondNodeWidget.tsx +++ b/demos/demo-custom-node1/DiamondNodeWidget.tsx @@ -39,10 +39,10 @@ export class DiamonNodeWidget extends React.Component - - - + + + - - ` + + ` }} />
PortModel; + + constructor(type: string, cb: (initialConfig?: any) => PortModel) { + super(type); + this.cb = cb; + } + + getNewInstance(initialConfig?: any): PortModel { + return this.cb(initialConfig); + } +} diff --git a/demos/demo-custom-node1/index.tsx b/demos/demo-custom-node1/index.tsx index f48af0e..e2ad1ab 100644 --- a/demos/demo-custom-node1/index.tsx +++ b/demos/demo-custom-node1/index.tsx @@ -11,7 +11,7 @@ import * as React from "react"; // import the custom models import { DiamondNodeModel } from "./DiamondNodeModel"; import { DiamondNodeFactory } from "./DiamondNodeFactory"; -import { SimplePortFactory } from "../../src/AbstractFactory"; +import { SimplePortFactory } from "./SimplePortFactory"; import { DiamondPortModel } from "./DiamondPortModel"; /** diff --git a/demos/demo-dagre/dagre-utils.ts b/demos/demo-dagre/dagre-utils.ts index 57588b4..207e1fe 100644 --- a/demos/demo-dagre/dagre-utils.ts +++ b/demos/demo-dagre/dagre-utils.ts @@ -22,9 +22,7 @@ function distributeGraph(model) { let edges = mapEdges(model); let graph = new dagre.graphlib.Graph(); graph.setGraph({}); - graph.setDefaultEdgeLabel(function() { - return {}; - }); + graph.setDefaultEdgeLabel(() => ({})); //add elements to dagre graph nodes.forEach(node => { graph.setNode(node.id, node.metadata); diff --git a/demos/demo-drag-and-drop/index.tsx b/demos/demo-drag-and-drop/index.tsx index 8540db9..61641cd 100644 --- a/demos/demo-drag-and-drop/index.tsx +++ b/demos/demo-drag-and-drop/index.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { BodyWidget } from "./components/BodyWidget"; import { Application } from "./Application"; -require("./sass/main.scss"); +import "./sass/main.scss"; export default () => { var app = new Application(); diff --git a/demos/demo-drag-and-drop/sass/main.scss b/demos/demo-drag-and-drop/sass/main.scss index 874495b..337993c 100644 --- a/demos/demo-drag-and-drop/sass/main.scss +++ b/demos/demo-drag-and-drop/sass/main.scss @@ -1,47 +1,47 @@ .body{ - flex-grow: 1; - display: flex; - flex-direction: column; - min-height: 100%; + flex-grow: 1; + display: flex; + flex-direction: column; + min-height: 100%; - .header{ - display: flex; - background: rgb(30,30,30); - flex-grow: 0; - flex-shrink: 0; - color: white; - font-family: Helvetica, Arial; - padding: 10px; - >*{ - align-self:center; - } - } + .header{ + display: flex; + background: rgb(30,30,30); + flex-grow: 0; + flex-shrink: 0; + color: white; + font-family: Helvetica, Arial; + padding: 10px; + >*{ + align-self:center; + } + } - .content{ - display: flex; - flex-grow: 1; + .content{ + display: flex; + flex-grow: 1; - .diagram-layer{ - position: relative; - flex-grow: 1; - } + .diagram-layer{ + position: relative; + flex-grow: 1; + } - .tray{ - min-width: 200px; - background: rgb(20,20,20); - flex-grow: 0; - flex-shrink: 0; + .tray{ + min-width: 200px; + background: rgb(20,20,20); + flex-grow: 0; + flex-shrink: 0; - .tray-item{ - color: white; - font-family: Helvetica, Arial; - padding: 5px; - margin: 0px 10px; - border: solid 1px; - border-radius: 5px; - margin-bottom: 2px; - cursor: pointer; - } - } - } + .tray-item{ + color: white; + font-family: Helvetica, Arial; + padding: 5px; + margin: 0px 10px; + border: solid 1px; + border-radius: 5px; + margin-bottom: 2px; + cursor: pointer; + } + } + } } diff --git a/demos/demo-performance/index.tsx b/demos/demo-performance/index.tsx index ff05e58..a684355 100644 --- a/demos/demo-performance/index.tsx +++ b/demos/demo-performance/index.tsx @@ -13,24 +13,6 @@ export default () => { var engine = new DiagramEngine(); engine.installDefaultFactories(); - function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { - //3-A) create a default node - var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)"); - var port1 = node1.addOutPort("Out"); - node1.setPosition(100 + offsetX, 100 + offsetY); - - //3-B) create another default node - var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)"); - var port2 = node2.addInPort("In"); - node2.setPosition(200 + offsetX, 100 + offsetY); - - //3-C) link the 2 nodes together - var link1 = port1.link(port2); - - //4) add the models to the root graph - model.addAll(node1, node2, link1); - } - //2) setup the diagram model var model = new DiagramModel(); @@ -46,3 +28,21 @@ export default () => { //6) render the diagram! return ; }; + +function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { + //3-A) create a default node + var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)"); + var port1 = node1.addOutPort("Out"); + node1.setPosition(100 + offsetX, 100 + offsetY); + + //3-B) create another default node + var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)"); + var port2 = node2.addInPort("In"); + node2.setPosition(200 + offsetX, 100 + offsetY); + + //3-C) link the 2 nodes together + var link1 = port1.link(port2); + + //4) add the models to the root graph + model.addAll(node1, node2, link1); +} diff --git a/demos/demo-serializing/index.tsx b/demos/demo-serializing/index.tsx index 9e03051..d453829 100644 --- a/demos/demo-serializing/index.tsx +++ b/demos/demo-serializing/index.tsx @@ -2,7 +2,7 @@ import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget import * as React from "react"; import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget"; import { action } from "@storybook/addon-actions"; -var beautify = require("json-beautify"); +import * as beautify from "json-beautify"; export default () => { //1) setup the diagram engine diff --git a/demos/demo-zoom-to-fit/index.tsx b/demos/demo-zoom-to-fit/index.tsx index 38d2209..15443ca 100644 --- a/demos/demo-zoom-to-fit/index.tsx +++ b/demos/demo-zoom-to-fit/index.tsx @@ -20,24 +20,6 @@ export default () => { var engine = new DiagramEngine(); engine.installDefaultFactories(); - function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { - //3-A) create a default node - var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)"); - var port1 = node1.addOutPort("Out"); - node1.setPosition(100 + offsetX, 100 + offsetY); - - //3-B) create another default node - var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)"); - var port2 = node2.addInPort("In"); - node2.setPosition(200 + offsetX, 100 + offsetY); - - //3-C) link the 2 nodes together - var link1 = port1.link(port2); - - //4) add the models to the root graph - model.addAll(node1, node2, link1); - } - //2) setup the diagram model var model = new DiagramModel(); @@ -57,3 +39,21 @@ export default () => { ); }; + +function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) { + //3-A) create a default node + var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)"); + var port1 = node1.addOutPort("Out"); + node1.setPosition(100 + offsetX, 100 + offsetY); + + //3-B) create another default node + var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)"); + var port2 = node2.addInPort("In"); + node2.setPosition(200 + offsetX, 100 + offsetY); + + //3-C) link the 2 nodes together + var link1 = port1.link(port2); + + //4) add the models to the root graph + model.addAll(node1, node2, link1); +} diff --git a/demos/index.tsx b/demos/index.tsx index 4cbef14..59a8551 100644 --- a/demos/index.tsx +++ b/demos/index.tsx @@ -6,7 +6,7 @@ import { Helper } from "./.helpers/Helper"; import { Toolkit } from "../src/Toolkit"; //include the SCSS for the demo -require("./.helpers/demo.scss"); +import "./.helpers/demo.scss"; Toolkit.TESTING = true; diff --git a/demos/tslint.json b/demos/tslint.json new file mode 100644 index 0000000..90605eb --- /dev/null +++ b/demos/tslint.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "../tslint.json" + ], + "rules": { + "no-console": false, + "max-classes-per-file": false, + "no-var-requires": false + } +} \ No newline at end of file diff --git a/package.json b/package.json index 1b261b0..050a0b9 100644 --- a/package.json +++ b/package.json @@ -20,13 +20,21 @@ "typings": "./dist/@types/src/main", "author": "dylanvorster", "scripts": { - "test:ci": "rm -rf ./dist && node ./tests/e2e/generate-e2e.js && jest --no-cache", - "test": "jest --no-cache", + "build:ts": "webpack", + "build:ts:prod": "cross-env NODE_ENV=production webpack", + "build:sass:prod": "node-sass --output-style compressed ./src/sass/main.scss > ./dist/style.min.css", + "storybook": "start-storybook -p 9001 -c .storybook", "storybook:build": "build-storybook -c .storybook -o .out", "storybook:github": "storybook-to-ghpages", - "prepublishOnly": "rm -rf ./dist && cross-env NODE_ENV=production webpack && ./node_modules/node-sass/bin/node-sass --output-style compressed ./src/sass/main.scss > ./dist/style.min.css", - "pretty": "prettier --use-tabs --write \"{src,demos}/**/*.{ts,tsx}\" --print-width 120" + + "pretty": "prettier --use-tabs --write \"{src,demos,tests}/**/*.{ts,tsx}\" --print-width 120", + "lint": "tslint -p .", + + "test:ci": "rm -rf ./dist && node ./tests/e2e/generate-e2e.js && jest --no-cache", + "test": "jest --no-cache", + + "prepublishOnly": "yarn run build:ts:prod && yarn run build:sass:prod" }, "dependencies": { "closest": "^0.0.1", diff --git a/src/AbstractFactory.ts b/src/AbstractFactory.ts deleted file mode 100644 index 25d99ca..0000000 --- a/src/AbstractFactory.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { BaseModel } from "./models/BaseModel"; -import { NodeModel } from "./models/NodeModel"; -import { LinkModel } from "./models/LinkModel"; -import { DiagramEngine } from "./DiagramEngine"; -import { PortModel } from "./models/PortModel"; -import { PointModel } from "./models/PointModel"; -import { LabelModel } from "./models/LabelModel"; - -export abstract class AbstractFactory { - type: string; - - constructor(name: string) { - this.type = name; - } - - getType(): string { - return this.type; - } - - abstract getNewInstance(initialConfig?: any): T; -} - -export abstract class NodeFactory extends AbstractFactory { - abstract generateReactWidget(diagramEngine: DiagramEngine, node: T): JSX.Element; -} - -export abstract class LinkFactory extends AbstractFactory { - abstract generateReactWidget(diagramEngine: DiagramEngine, link: T): JSX.Element; -} - -export abstract class LabelFactory extends AbstractFactory { - abstract generateReactWidget(diagramEngine: DiagramEngine, label: T): JSX.Element; -} - -export abstract class PortFactory extends AbstractFactory {} - -export class SimplePortFactory extends PortFactory { - cb: (initialConfig?: any) => PortModel; - - constructor(type: string, cb: (initialConfig?: any) => PortModel) { - super(type); - this.cb = cb; - } - - getNewInstance(initialConfig?: any): PortModel { - return this.cb(initialConfig); - } -} diff --git a/src/BaseEntity.ts b/src/BaseEntity.ts index 711522b..6ec9a38 100644 --- a/src/BaseEntity.ts +++ b/src/BaseEntity.ts @@ -33,9 +33,11 @@ export class BaseEntity { return this.id; } - doClone(lookupTable = {}, clone) {} + doClone(lookupTable: { [s: string]: any } = {}, clone: any) { + /*noop*/ + } - clone(lookupTable = {}) { + clone(lookupTable: { [s: string]: any } = {}) { // try and use an existing clone first if (lookupTable[this.id]) { return lookupTable[this.id]; @@ -53,7 +55,7 @@ export class BaseEntity { this.listeners = {}; } - public deSerialize(data, engine: DiagramEngine) { + public deSerialize(data: { [s: string]: any }, engine: DiagramEngine) { this.id = data.id; } @@ -72,12 +74,15 @@ export class BaseEntity { event.firing = false; } }; + for (var i in this.listeners) { - // propagation stopped - if (!event.firing) { - return; + if (this.listeners.hasOwnProperty(i)) { + // propagation stopped + if (!event.firing) { + return; + } + cb(this.listeners[i], event); } - cb(this.listeners[i], event); } } diff --git a/src/CanvasActions.ts b/src/CanvasActions.ts deleted file mode 100644 index bb7675f..0000000 --- a/src/CanvasActions.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { DiagramModel } from "./models/DiagramModel"; -import { DiagramEngine } from "./DiagramEngine"; -import { SelectionModel } from "./widgets/DiagramWidget"; -import { PointModel } from "./models/PointModel"; -import { NodeModel } from "./models/NodeModel"; - -export class BaseAction { - mouseX: number; - mouseY: number; - ms: number; - - constructor(mouseX: number, mouseY: number) { - this.mouseX = mouseX; - this.mouseY = mouseY; - this.ms = new Date().getTime(); - } -} - -export class SelectingAction extends BaseAction { - mouseX2: number; - mouseY2: number; - - constructor(mouseX: number, mouseY: number) { - super(mouseX, mouseY); - this.mouseX2 = mouseX; - this.mouseY2 = mouseY; - } - - getBoxDimensions() { - return { - left: this.mouseX2 > this.mouseX ? this.mouseX : this.mouseX2, - top: this.mouseY2 > this.mouseY ? this.mouseY : this.mouseY2, - width: Math.abs(this.mouseX2 - this.mouseX), - height: Math.abs(this.mouseY2 - this.mouseY), - right: this.mouseX2 < this.mouseX ? this.mouseX : this.mouseX2, - bottom: this.mouseY2 < this.mouseY ? this.mouseY : this.mouseY2 - }; - } - - containsElement(x: number, y: number, diagramModel: DiagramModel): boolean { - var z = diagramModel.getZoomLevel() / 100.0; - let dimensions = this.getBoxDimensions(); - - return ( - x * z + diagramModel.getOffsetX() > dimensions.left && - x * z + diagramModel.getOffsetX() < dimensions.right && - y * z + diagramModel.getOffsetY() > dimensions.top && - y * z + diagramModel.getOffsetY() < dimensions.bottom - ); - } -} - -export class MoveCanvasAction extends BaseAction { - initialOffsetX: number; - initialOffsetY: number; - - constructor(mouseX: number, mouseY: number, diagramModel: DiagramModel) { - super(mouseX, mouseY); - this.initialOffsetX = diagramModel.getOffsetX(); - this.initialOffsetY = diagramModel.getOffsetY(); - } -} - -export class MoveItemsAction extends BaseAction { - selectionModels: SelectionModel[]; - moved: boolean; - - constructor(mouseX: number, mouseY: number, diagramEngine: DiagramEngine) { - super(mouseX, mouseY); - this.moved = false; - diagramEngine.enableRepaintEntities(diagramEngine.getDiagramModel().getSelectedItems()); - var selectedItems = diagramEngine.getDiagramModel().getSelectedItems(); - - //dont allow items which are locked to move - selectedItems = selectedItems.filter(item => { - return !diagramEngine.isModelLocked(item); - }); - - this.selectionModels = selectedItems.map((item: PointModel | NodeModel) => { - return { - model: item, - initialX: item.x, - initialY: item.y - }; - }); - } -} diff --git a/src/DiagramEngine.ts b/src/DiagramEngine.ts index 66728b3..4267dfd 100644 --- a/src/DiagramEngine.ts +++ b/src/DiagramEngine.ts @@ -6,7 +6,10 @@ import { NodeModel } from "./models/NodeModel"; import { PointModel } from "./models/PointModel"; import { PortModel } from "./models/PortModel"; import { LinkModel } from "./models/LinkModel"; -import { LabelFactory, LinkFactory, NodeFactory, PortFactory } from "./AbstractFactory"; +import { AbstractLabelFactory } from "./factories/AbstractLabelFactory"; +import { AbstractLinkFactory } from "./factories/AbstractLinkFactory"; +import { AbstractNodeFactory } from "./factories/AbstractNodeFactory"; +import { AbstractPortFactory } from "./factories/AbstractPortFactory"; import { DefaultLinkFactory, DefaultNodeFactory } from "./main"; import { ROUTING_SCALING_FACTOR } from "./routing/PathFinding"; import { DefaultPortFactory } from "./defaults/factories/DefaultPortFactory"; @@ -32,10 +35,10 @@ export interface DiagramEngineListener extends BaseListener { * Passed as a parameter to the DiagramWidget */ export class DiagramEngine extends BaseEntity { - nodeFactories: { [s: string]: NodeFactory }; - linkFactories: { [s: string]: LinkFactory }; - portFactories: { [s: string]: PortFactory }; - labelFactories: { [s: string]: LabelFactory }; + nodeFactories: { [s: string]: AbstractNodeFactory }; + linkFactories: { [s: string]: AbstractLinkFactory }; + portFactories: { [s: string]: AbstractPortFactory }; + labelFactories: { [s: string]: AbstractLabelFactory }; diagramModel: DiagramModel; canvas: Element; @@ -82,7 +85,9 @@ export class DiagramEngine extends BaseEntity { repaintCanvas() { this.iterateListeners(listener => { - listener.repaintCanvas && listener.repaintCanvas(); + if (listener.repaintCanvas) { + listener.repaintCanvas(); + } }); } @@ -152,19 +157,19 @@ export class DiagramEngine extends BaseEntity { //!-------------- FACTORIES ------------ - getNodeFactories(): { [s: string]: NodeFactory } { + getNodeFactories(): { [s: string]: AbstractNodeFactory } { return this.nodeFactories; } - getLinkFactories(): { [s: string]: LinkFactory } { + getLinkFactories(): { [s: string]: AbstractLinkFactory } { return this.linkFactories; } - getLabelFactories(): { [s: string]: LabelFactory } { + getLabelFactories(): { [s: string]: AbstractLabelFactory } { return this.labelFactories; } - registerLabelFactory(factory: LabelFactory) { + registerLabelFactory(factory: AbstractLabelFactory) { this.labelFactories[factory.getType()] = factory; this.iterateListeners(listener => { if (listener.labelFactoriesUpdated) { @@ -173,7 +178,7 @@ export class DiagramEngine extends BaseEntity { }); } - registerPortFactory(factory: PortFactory) { + registerPortFactory(factory: AbstractPortFactory) { this.portFactories[factory.getType()] = factory; this.iterateListeners(listener => { if (listener.portFactoriesUpdated) { @@ -182,7 +187,7 @@ export class DiagramEngine extends BaseEntity { }); } - registerNodeFactory(factory: NodeFactory) { + registerNodeFactory(factory: AbstractNodeFactory) { this.nodeFactories[factory.getType()] = factory; this.iterateListeners(listener => { if (listener.nodeFactoriesUpdated) { @@ -191,7 +196,7 @@ export class DiagramEngine extends BaseEntity { }); } - registerLinkFactory(factory: LinkFactory) { + registerLinkFactory(factory: AbstractLinkFactory) { this.linkFactories[factory.getType()] = factory; this.iterateListeners(listener => { if (listener.linkFactoriesUpdated) { @@ -200,47 +205,43 @@ export class DiagramEngine extends BaseEntity { }); } - getPortFactory(type: string): PortFactory { + getPortFactory(type: string): AbstractPortFactory { if (this.portFactories[type]) { return this.portFactories[type]; } - console.log("cannot find factory for port of type: [" + type + "]"); - return null; + throw new Error(`cannot find factory for port of type: [${type}]`); } - getNodeFactory(type: string): NodeFactory { + getNodeFactory(type: string): AbstractNodeFactory { if (this.nodeFactories[type]) { return this.nodeFactories[type]; } - console.log("cannot find factory for node of type: [" + type + "]"); - return null; + throw new Error(`cannot find factory for node of type: [${type}]`); } - getLinkFactory(type: string): LinkFactory { + getLinkFactory(type: string): AbstractLinkFactory { if (this.linkFactories[type]) { return this.linkFactories[type]; } - console.log("cannot find factory for link of type: [" + type + "]"); - return null; + throw new Error(`cannot find factory for link of type: [${type}]`); } - getLabelFactory(type: string): LabelFactory { + getLabelFactory(type: string): AbstractLabelFactory { if (this.labelFactories[type]) { return this.labelFactories[type]; } - console.log("cannot find factory for label of type: [" + type + "]"); - return null; + throw new Error(`cannot find factory for label of type: [${type}]`); } - getFactoryForNode(node: NodeModel): NodeFactory | null { + getFactoryForNode(node: NodeModel): AbstractNodeFactory | null { return this.getNodeFactory(node.getType()); } - getFactoryForLink(link: LinkModel): LinkFactory | null { + getFactoryForLink(link: LinkModel): AbstractLinkFactory | null { return this.getLinkFactory(link.getType()); } - getFactoryForLabel(label: LabelModel): LabelFactory | null { + getFactoryForLabel(label: LabelModel): AbstractLabelFactory | null { return this.getLabelFactory(label.getType()); } @@ -274,7 +275,7 @@ export class DiagramEngine extends BaseEntity { } getNodeElement(node: NodeModel): Element { - const selector = this.canvas.querySelector('.node[data-nodeid="' + node.getID() + '"]'); + const selector = this.canvas.querySelector(`.node[data-nodeid="${node.getID()}"]`); if (selector === null) { throw new Error("Cannot find Node element with nodeID: [" + node.getID() + "]"); } @@ -283,7 +284,7 @@ export class DiagramEngine extends BaseEntity { getNodePortElement(port: PortModel): any { var selector = this.canvas.querySelector( - '.port[data-name="' + port.getName() + '"][data-nodeid="' + port.getParent().getID() + '"]' + `.port[data-name="${port.getName()}"][data-nodeid="${port.getParent().getID()}"]` ); if (selector === null) { throw new Error( diff --git a/src/Toolkit.ts b/src/Toolkit.ts index cfeb62e..499a1ec 100644 --- a/src/Toolkit.ts +++ b/src/Toolkit.ts @@ -1,3 +1,4 @@ +// tslint:disable no-bitwise import closest = require("closest"); import { PointModel } from "./models/PointModel"; import { ROUTING_SCALING_FACTOR } from "./routing/PathFinding"; @@ -18,9 +19,9 @@ export class Toolkit { Toolkit.TESTING_UID++; return "" + Toolkit.TESTING_UID; } - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - var r = (Math.random() * 16) | 0, - v = c == "x" ? r : (r & 0x3) | 0x8; + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, c => { + const r = (Math.random() * 16) | 0; + const v = c === "x" ? r : (r & 0x3) | 0x8; return v.toString(16); }); } @@ -48,7 +49,7 @@ export class Toolkit { var curvyY = isHorizontal ? 0 : curvy; return `M${firstPoint.x},${firstPoint.y} C ${firstPoint.x + curvyX},${firstPoint.y + curvyY} - ${lastPoint.x - curvyX},${lastPoint.y - curvyY} ${lastPoint.x},${lastPoint.y}`; + ${lastPoint.x - curvyX},${lastPoint.y - curvyY} ${lastPoint.x},${lastPoint.y}`; } public static generateDynamicPath(pathCoords: number[][]) { diff --git a/src/actions/BaseAction.ts b/src/actions/BaseAction.ts new file mode 100644 index 0000000..22ee946 --- /dev/null +++ b/src/actions/BaseAction.ts @@ -0,0 +1,11 @@ +export class BaseAction { + mouseX: number; + mouseY: number; + ms: number; + + constructor(mouseX: number, mouseY: number) { + this.mouseX = mouseX; + this.mouseY = mouseY; + this.ms = new Date().getTime(); + } +} diff --git a/src/actions/MoveCanvasAction.ts b/src/actions/MoveCanvasAction.ts new file mode 100644 index 0000000..9b2fed7 --- /dev/null +++ b/src/actions/MoveCanvasAction.ts @@ -0,0 +1,13 @@ +import { BaseAction } from "./BaseAction"; +import { DiagramModel } from "../models/DiagramModel"; + +export class MoveCanvasAction extends BaseAction { + initialOffsetX: number; + initialOffsetY: number; + + constructor(mouseX: number, mouseY: number, diagramModel: DiagramModel) { + super(mouseX, mouseY); + this.initialOffsetX = diagramModel.getOffsetX(); + this.initialOffsetY = diagramModel.getOffsetY(); + } +} diff --git a/src/actions/MoveItemsAction.ts b/src/actions/MoveItemsAction.ts new file mode 100644 index 0000000..dbaedef --- /dev/null +++ b/src/actions/MoveItemsAction.ts @@ -0,0 +1,30 @@ +import { BaseAction } from "./BaseAction"; +import { SelectionModel } from "../models/SelectionModel"; +import { PointModel } from "../models/PointModel"; +import { NodeModel } from "../models/NodeModel"; +import { DiagramEngine } from "../DiagramEngine"; + +export class MoveItemsAction extends BaseAction { + selectionModels: SelectionModel[]; + moved: boolean; + + constructor(mouseX: number, mouseY: number, diagramEngine: DiagramEngine) { + super(mouseX, mouseY); + this.moved = false; + diagramEngine.enableRepaintEntities(diagramEngine.getDiagramModel().getSelectedItems()); + var selectedItems = diagramEngine.getDiagramModel().getSelectedItems(); + + //dont allow items which are locked to move + selectedItems = selectedItems.filter(item => { + return !diagramEngine.isModelLocked(item); + }); + + this.selectionModels = selectedItems.map((item: PointModel | NodeModel) => { + return { + model: item, + initialX: item.x, + initialY: item.y + }; + }); + } +} diff --git a/src/actions/SelectingAction.ts b/src/actions/SelectingAction.ts new file mode 100644 index 0000000..f188e5a --- /dev/null +++ b/src/actions/SelectingAction.ts @@ -0,0 +1,36 @@ +import { BaseAction } from "./BaseAction"; +import { DiagramModel } from "../models/DiagramModel"; + +export class SelectingAction extends BaseAction { + mouseX2: number; + mouseY2: number; + + constructor(mouseX: number, mouseY: number) { + super(mouseX, mouseY); + this.mouseX2 = mouseX; + this.mouseY2 = mouseY; + } + + getBoxDimensions() { + return { + left: this.mouseX2 > this.mouseX ? this.mouseX : this.mouseX2, + top: this.mouseY2 > this.mouseY ? this.mouseY : this.mouseY2, + width: Math.abs(this.mouseX2 - this.mouseX), + height: Math.abs(this.mouseY2 - this.mouseY), + right: this.mouseX2 < this.mouseX ? this.mouseX : this.mouseX2, + bottom: this.mouseY2 < this.mouseY ? this.mouseY : this.mouseY2 + }; + } + + containsElement(x: number, y: number, diagramModel: DiagramModel): boolean { + var z = diagramModel.getZoomLevel() / 100.0; + let dimensions = this.getBoxDimensions(); + + return ( + x * z + diagramModel.getOffsetX() > dimensions.left && + x * z + diagramModel.getOffsetX() < dimensions.right && + y * z + diagramModel.getOffsetY() > dimensions.top && + y * z + diagramModel.getOffsetY() < dimensions.bottom + ); + } +} diff --git a/src/defaults/factories/DefaultLabelFactory.tsx b/src/defaults/factories/DefaultLabelFactory.tsx index b00109f..544e28c 100644 --- a/src/defaults/factories/DefaultLabelFactory.tsx +++ b/src/defaults/factories/DefaultLabelFactory.tsx @@ -1,13 +1,13 @@ import * as React from "react"; import { DiagramEngine } from "../../DiagramEngine"; -import { LabelFactory } from "../../AbstractFactory"; +import { AbstractLabelFactory } from "../../factories/AbstractLabelFactory"; import { DefaultLabelModel } from "../models/DefaultLabelModel"; import { DefaultLabelWidget } from "../widgets/DefaultLabelWidget"; /** * @author Dylan Vorster */ -export class DefaultLabelFactory extends LabelFactory { +export class DefaultLabelFactory extends AbstractLabelFactory { constructor() { super("default"); } diff --git a/src/defaults/factories/DefaultLinkFactory.tsx b/src/defaults/factories/DefaultLinkFactory.tsx index 457dc79..a4ca8e8 100644 --- a/src/defaults/factories/DefaultLinkFactory.tsx +++ b/src/defaults/factories/DefaultLinkFactory.tsx @@ -1,13 +1,13 @@ import * as React from "react"; import { DefaultLinkWidget } from "../widgets/DefaultLinkWidget"; import { DiagramEngine } from "../../DiagramEngine"; -import { LinkFactory } from "../../AbstractFactory"; +import { AbstractLinkFactory } from "../../factories/AbstractLinkFactory"; import { DefaultLinkModel } from "../models/DefaultLinkModel"; /** * @author Dylan Vorster */ -export class DefaultLinkFactory extends LinkFactory { +export class DefaultLinkFactory extends AbstractLinkFactory { constructor() { super("default"); } diff --git a/src/defaults/factories/DefaultNodeFactory.ts b/src/defaults/factories/DefaultNodeFactory.ts index 0783b41..c9a82cc 100644 --- a/src/defaults/factories/DefaultNodeFactory.ts +++ b/src/defaults/factories/DefaultNodeFactory.ts @@ -2,11 +2,11 @@ import { DefaultNodeModel } from "../models/DefaultNodeModel"; import * as React from "react"; import { DefaultNodeWidget } from "../widgets/DefaultNodeWidget"; import { DiagramEngine } from "../../DiagramEngine"; -import { NodeFactory } from "../../AbstractFactory"; +import { AbstractNodeFactory } from "../../factories/AbstractNodeFactory"; /** * @author Dylan Vorster */ -export class DefaultNodeFactory extends NodeFactory { +export class DefaultNodeFactory extends AbstractNodeFactory { constructor() { super("default"); } diff --git a/src/defaults/factories/DefaultPortFactory.tsx b/src/defaults/factories/DefaultPortFactory.tsx index 647553b..aa03e52 100644 --- a/src/defaults/factories/DefaultPortFactory.tsx +++ b/src/defaults/factories/DefaultPortFactory.tsx @@ -1,7 +1,7 @@ import { DefaultPortModel } from "../models/DefaultPortModel"; -import { PortFactory } from "../../AbstractFactory"; +import { AbstractPortFactory } from "../../factories/AbstractPortFactory"; -export class DefaultPortFactory extends PortFactory { +export class DefaultPortFactory extends AbstractPortFactory { constructor() { super("default"); } diff --git a/src/defaults/models/DefaultLinkModel.ts b/src/defaults/models/DefaultLinkModel.ts index 9ac53a6..500a9d1 100644 --- a/src/defaults/models/DefaultLinkModel.ts +++ b/src/defaults/models/DefaultLinkModel.ts @@ -10,9 +10,9 @@ import { DefaultLabelModel } from "./DefaultLabelModel"; import { LabelModel } from "../../models/LabelModel"; export interface DefaultLinkModelListener extends LinkModelListener { - colorChanged?(event: BaseEvent & { color: null | string }); + colorChanged?(event: BaseEvent & { color: null | string }): void; - widthChanged?(event: BaseEvent & { width: 0 | number }); + widthChanged?(event: BaseEvent & { width: 0 | number }): void; } export class DefaultLinkModel extends LinkModel { @@ -54,14 +54,18 @@ export class DefaultLinkModel extends LinkModel { setWidth(width: number) { this.width = width; this.iterateListeners((listener: DefaultLinkModelListener, event: BaseEvent) => { - listener.widthChanged && listener.widthChanged({ ...event, width: width }); + if (listener.widthChanged) { + listener.widthChanged({ ...event, width: width }); + } }); } setColor(color: string) { this.color = color; this.iterateListeners((listener: DefaultLinkModelListener, event: BaseEvent) => { - listener.colorChanged && listener.colorChanged({ ...event, color: color }); + if (listener.colorChanged) { + listener.colorChanged({ ...event, color: color }); + } }); } } diff --git a/src/defaults/widgets/DefaultLinkWidget.tsx b/src/defaults/widgets/DefaultLinkWidget.tsx index f4611c7..78d03cd 100644 --- a/src/defaults/widgets/DefaultLinkWidget.tsx +++ b/src/defaults/widgets/DefaultLinkWidget.tsx @@ -343,18 +343,18 @@ export class DefaultLinkWidget extends BaseWidget { - this.addPointToLink(event, i + 1); + this.addPointToLink(event, j + 1); } }, - i + j ) ); } diff --git a/src/factories/AbstractFactory.ts b/src/factories/AbstractFactory.ts new file mode 100644 index 0000000..ba2433b --- /dev/null +++ b/src/factories/AbstractFactory.ts @@ -0,0 +1,15 @@ +import { BaseModel } from "../models/BaseModel"; + +export abstract class AbstractFactory { + type: string; + + constructor(name: string) { + this.type = name; + } + + getType(): string { + return this.type; + } + + abstract getNewInstance(initialConfig?: any): T; +} diff --git a/src/factories/AbstractLabelFactory.ts b/src/factories/AbstractLabelFactory.ts new file mode 100644 index 0000000..77e1418 --- /dev/null +++ b/src/factories/AbstractLabelFactory.ts @@ -0,0 +1,7 @@ +import { LabelModel } from "../models/LabelModel"; +import { DiagramEngine } from "../DiagramEngine"; +import { AbstractFactory } from "./AbstractFactory"; + +export abstract class AbstractLabelFactory extends AbstractFactory { + abstract generateReactWidget(diagramEngine: DiagramEngine, link: T): JSX.Element; +} diff --git a/src/factories/AbstractLinkFactory.ts b/src/factories/AbstractLinkFactory.ts new file mode 100644 index 0000000..e1a790e --- /dev/null +++ b/src/factories/AbstractLinkFactory.ts @@ -0,0 +1,7 @@ +import { LinkModel } from "../models/LinkModel"; +import { DiagramEngine } from "../DiagramEngine"; +import { AbstractFactory } from "./AbstractFactory"; + +export abstract class AbstractLinkFactory extends AbstractFactory { + abstract generateReactWidget(diagramEngine: DiagramEngine, link: T): JSX.Element; +} diff --git a/src/factories/AbstractNodeFactory.ts b/src/factories/AbstractNodeFactory.ts new file mode 100644 index 0000000..4994922 --- /dev/null +++ b/src/factories/AbstractNodeFactory.ts @@ -0,0 +1,7 @@ +import { NodeModel } from "../models/NodeModel"; +import { DiagramEngine } from "../DiagramEngine"; +import { AbstractFactory } from "./AbstractFactory"; + +export abstract class AbstractNodeFactory extends AbstractFactory { + abstract generateReactWidget(diagramEngine: DiagramEngine, node: T): JSX.Element; +} diff --git a/src/factories/AbstractPortFactory.ts b/src/factories/AbstractPortFactory.ts new file mode 100644 index 0000000..a8bf463 --- /dev/null +++ b/src/factories/AbstractPortFactory.ts @@ -0,0 +1,5 @@ +import { PortModel } from "../models/PortModel"; +import { DiagramEngine } from "../DiagramEngine"; +import { AbstractFactory } from "./AbstractFactory"; + +export abstract class AbstractPortFactory extends AbstractFactory {} diff --git a/src/main.ts b/src/main.ts index 0338a4d..9fc17bc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,14 +15,24 @@ export * from "./defaults/widgets/DefaultLinkWidget"; export * from "./defaults/widgets/DefaultNodeWidget"; export * from "./defaults/widgets/DefaultPortLabelWidget"; -export * from "./AbstractFactory"; +export * from "./factories/AbstractFactory"; +export * from "./factories/AbstractLabelFactory"; +export * from "./factories/AbstractLinkFactory"; +export * from "./factories/AbstractNodeFactory"; +export * from "./factories/AbstractPortFactory"; + export * from "./Toolkit"; export * from "./DiagramEngine"; -export * from "./models/DiagramModel"; export * from "./BaseEntity"; -export * from "./CanvasActions"; +export * from "./actions/BaseAction"; +export * from "./actions/MoveCanvasAction"; +export * from "./actions/MoveItemsAction"; +export * from "./actions/SelectingAction"; + +export * from "./models/SelectionModel"; +export * from "./models/DiagramModel"; export * from "./models/BaseModel"; export * from "./models/DiagramModel"; export * from "./models/LinkModel"; diff --git a/src/models/DiagramModel.ts b/src/models/DiagramModel.ts index 13c3ddc..6e7a8e4 100644 --- a/src/models/DiagramModel.ts +++ b/src/models/DiagramModel.ts @@ -53,7 +53,9 @@ export class DiagramModel extends BaseEntity { setGridSize(size: number = 0) { this.gridSize = size; this.iterateListeners((listener, event) => { - listener.gridUpdated && listener.gridUpdated({ ...event, size: size }); + if (listener.gridUpdated) { + listener.gridUpdated({ ...event, size: size }); + } }); } @@ -169,7 +171,9 @@ export class DiagramModel extends BaseEntity { this.zoom = zoom; this.iterateListeners((listener, event) => { - listener.zoomUpdated && listener.zoomUpdated({ ...event, zoom: zoom }); + if (listener.zoomUpdated) { + listener.zoomUpdated({ ...event, zoom: zoom }); + } }); } @@ -177,22 +181,27 @@ export class DiagramModel extends BaseEntity { this.offsetX = offsetX; this.offsetY = offsetY; this.iterateListeners((listener, event) => { - listener.offsetUpdated && listener.offsetUpdated({ ...event, offsetX: offsetX, offsetY: offsetY }); + if (listener.offsetUpdated) { + listener.offsetUpdated({ ...event, offsetX: offsetX, offsetY: offsetY }); + } }); } setOffsetX(offsetX: number) { this.offsetX = offsetX; this.iterateListeners((listener, event) => { - listener.offsetUpdated && listener.offsetUpdated({ ...event, offsetX: offsetX, offsetY: this.offsetY }); + if (listener.offsetUpdated) { + listener.offsetUpdated({ ...event, offsetX: offsetX, offsetY: this.offsetY }); + } }); } setOffsetY(offsetY: number) { this.offsetY = offsetY; this.iterateListeners((listener, event) => { - listener.offsetUpdated && + if (listener.offsetUpdated) { listener.offsetUpdated({ ...event, offsetX: this.offsetX, offsetY: this.offsetY }); + } }); } @@ -247,7 +256,9 @@ export class DiagramModel extends BaseEntity { }); this.links[link.getID()] = link; this.iterateListeners((listener, event) => { - listener.linksUpdated && listener.linksUpdated({ ...event, link: link, isCreated: true }); + if (listener.linksUpdated) { + listener.linksUpdated({ ...event, link: link, isCreated: true }); + } }); return link; } @@ -260,7 +271,9 @@ export class DiagramModel extends BaseEntity { }); this.nodes[node.getID()] = node; this.iterateListeners((listener, event) => { - listener.nodesUpdated && listener.nodesUpdated({ ...event, node: node, isCreated: true }); + if (listener.nodesUpdated) { + listener.nodesUpdated({ ...event, node: node, isCreated: true }); + } }); return node; } @@ -269,7 +282,9 @@ export class DiagramModel extends BaseEntity { link = this.getLink(link); delete this.links[link.getID()]; this.iterateListeners((listener, event) => { - listener.linksUpdated && listener.linksUpdated({ ...event, link: link as LinkModel, isCreated: false }); + if (listener.linksUpdated) { + listener.linksUpdated({ ...event, link: link as LinkModel, isCreated: false }); + } }); } @@ -277,7 +292,9 @@ export class DiagramModel extends BaseEntity { node = this.getNode(node); delete this.nodes[node.getID()]; this.iterateListeners((listener, event) => { - listener.nodesUpdated && listener.nodesUpdated({ ...event, node: node as NodeModel, isCreated: false }); + if (listener.nodesUpdated) { + listener.nodesUpdated({ ...event, node: node as NodeModel, isCreated: false }); + } }); } diff --git a/src/models/LinkModel.ts b/src/models/LinkModel.ts index 313f340..48aa680 100644 --- a/src/models/LinkModel.ts +++ b/src/models/LinkModel.ts @@ -158,7 +158,9 @@ export class LinkModel extends } this.sourcePort = port; this.iterateListeners((listener: LinkModelListener, event) => { - listener.sourcePortChanged && listener.sourcePortChanged({ ...event, port: port }); + if (listener.sourcePortChanged) { + listener.sourcePortChanged({ ...event, port: port }); + } }); } @@ -180,7 +182,9 @@ export class LinkModel extends } this.targetPort = port; this.iterateListeners((listener: LinkModelListener, event) => { - listener.targetPortChanged && listener.targetPortChanged({ ...event, port: port }); + if (listener.targetPortChanged) { + listener.targetPortChanged({ ...event, port: port }); + } }); } @@ -222,7 +226,7 @@ export class LinkModel extends } } - addPoint(pointModel: T, index = 1): T { + addPoint

(pointModel: P, index = 1): P { pointModel.setParent(this); this.points.splice(index, 0, pointModel); return pointModel; diff --git a/src/models/NodeModel.ts b/src/models/NodeModel.ts index 08b5b48..8641e23 100644 --- a/src/models/NodeModel.ts +++ b/src/models/NodeModel.ts @@ -26,14 +26,13 @@ export class NodeModel extends BaseModel { //store position let oldX = this.x; let oldY = this.y; - for (let port in this.ports) { - _.forEach(this.ports[port].getLinks(), link => { - let point = link.getPointForPort(this.ports[port]); + _.forEach(this.ports, port => { + _.forEach(port.getLinks(), link => { + let point = link.getPointForPort(port); point.x = point.x + x - oldX; point.y = point.y + y - oldY; }); - } - + }); this.x = x; this.y = y; } @@ -43,13 +42,13 @@ export class NodeModel extends BaseModel { // add the points of each link that are selected here if (this.isSelected()) { - for (let portName in this.ports) { + _.forEach(this.ports, port => { entities = entities.concat( - _.map(this.ports[portName].getLinks(), link => { - return link.getPointForPort(this.ports[portName]); + _.map(port.getLinks(), link => { + return link.getPointForPort(port); }) ); - } + }); } return entities; } @@ -82,18 +81,18 @@ export class NodeModel extends BaseModel { doClone(lookupTable = {}, clone) { // also clone the ports clone.ports = {}; - _.values(this.ports).forEach(port => { + _.forEach(this.ports, port => { clone.addPort(port.clone(lookupTable)); }); } remove() { super.remove(); - for (var i in this.ports) { - _.forEach(this.ports[i].getLinks(), link => { + _.forEach(this.ports, port => { + _.forEach(port.getLinks(), link => { link.remove(); }); - } + }); } getPortFromID(id): PortModel | null { diff --git a/src/models/SelectionModel.ts b/src/models/SelectionModel.ts new file mode 100644 index 0000000..5dbeaab --- /dev/null +++ b/src/models/SelectionModel.ts @@ -0,0 +1,8 @@ +import { BaseModel, BaseModelListener } from "./BaseModel"; +import { BaseEntity } from "../BaseEntity"; + +export interface SelectionModel { + model: BaseModel; + initialX: number; + initialY: number; +} diff --git a/src/sass/_DiagramWidget.scss b/src/sass/_DiagramWidget.scss index eb23927..c18b086 100644 --- a/src/sass/_DiagramWidget.scss +++ b/src/sass/_DiagramWidget.scss @@ -1,13 +1,13 @@ .srd-diagram{ - position: relative; - flex-grow: 1; - display: flex; - cursor: move; - overflow: hidden; + position: relative; + flex-grow: 1; + display: flex; + cursor: move; + overflow: hidden; - &__selector{ - position: absolute; - background-color: rgba(0,192,255,0.2); - border: solid 2px rgb(0,192,255); - } + &__selector{ + position: absolute; + background-color: rgba(0,192,255,0.2); + border: solid 2px rgb(0,192,255); + } } \ No newline at end of file diff --git a/src/sass/_LinkLayerWidget.scss b/src/sass/_LinkLayerWidget.scss index e6fc7ed..5c5875c 100644 --- a/src/sass/_LinkLayerWidget.scss +++ b/src/sass/_LinkLayerWidget.scss @@ -1,11 +1,11 @@ .srd-link-layer{ - position: absolute; - height: 100%; - width: 100%; - transform-origin: 0 0; - overflow: visible !important; - top:0; - bottom: 0; - left: 0; - right: 0; + position: absolute; + height: 100%; + width: 100%; + transform-origin: 0 0; + overflow: visible !important; + top:0; + bottom: 0; + left: 0; + right: 0; } \ No newline at end of file diff --git a/src/sass/_NodeLayerWidget.scss b/src/sass/_NodeLayerWidget.scss index f249842..65dd5b0 100644 --- a/src/sass/_NodeLayerWidget.scss +++ b/src/sass/_NodeLayerWidget.scss @@ -1,11 +1,11 @@ .srd-node-layer{ - top:0; - left:0; - right:0; - bottom:0; - position: absolute; - pointer-events: none; - transform-origin: 0 0; - width: 100%; - height: 100%; + top:0; + left:0; + right:0; + bottom:0; + position: absolute; + pointer-events: none; + transform-origin: 0 0; + width: 100%; + height: 100%; } \ No newline at end of file diff --git a/src/sass/_NodeWidget.scss b/src/sass/_NodeWidget.scss index 49c7878..a8d85de 100644 --- a/src/sass/_NodeWidget.scss +++ b/src/sass/_NodeWidget.scss @@ -1,14 +1,14 @@ .srd-node{ - position: absolute; - -webkit-touch-callout: none; /* iOS Safari */ - -webkit-user-select: none; /* Chrome/Safari/Opera */ - user-select: none; - cursor: move; - pointer-events: all; + position: absolute; + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Chrome/Safari/Opera */ + user-select: none; + cursor: move; + pointer-events: all; - &--selected{ - > * { - border-color:rgb(0,192,255) !important; - } - } + &--selected{ + > * { + border-color:rgb(0,192,255) !important; + } + } } \ No newline at end of file diff --git a/src/sass/_PortWidget.scss b/src/sass/_PortWidget.scss index f6213cf..578d23b 100644 --- a/src/sass/_PortWidget.scss +++ b/src/sass/_PortWidget.scss @@ -1,9 +1,9 @@ .srd-port{ - width: 15px; - height: 15px; - background: rgba(white,0.1); - - &:hover,&.selected{ - background: rgb(192,255,0); - } + width: 15px; + height: 15px; + background: rgba(white,0.1); + + &:hover,&.selected{ + background: rgb(192,255,0); + } } \ No newline at end of file diff --git a/src/sass/defaults/_DefaultLabelWidget.scss b/src/sass/defaults/_DefaultLabelWidget.scss index de73369..e1bae61 100644 --- a/src/sass/defaults/_DefaultLabelWidget.scss +++ b/src/sass/defaults/_DefaultLabelWidget.scss @@ -1,9 +1,9 @@ .srd-default-label{ - background: rgba(70, 70, 70, 0.8); - border: 1px solid #333; - border-radius: 4px; - color: #fff; - display: inline-block; - font-size: smaller; - padding: 5px; + background: rgba(70, 70, 70, 0.8); + border: 1px solid #333; + border-radius: 4px; + color: #fff; + display: inline-block; + font-size: smaller; + padding: 5px; } \ No newline at end of file diff --git a/src/sass/defaults/_DefaultLinkWidget.scss b/src/sass/defaults/_DefaultLinkWidget.scss index a286524..ba37cb4 100644 --- a/src/sass/defaults/_DefaultLinkWidget.scss +++ b/src/sass/defaults/_DefaultLinkWidget.scss @@ -1,39 +1,39 @@ .srd-default-link{ - @keyframes dash { - from { - stroke-dashoffset: 24; - } - to { - stroke-dashoffset: 0; - } - } + @keyframes dash { + from { + stroke-dashoffset: 24; + } + to { + stroke-dashoffset: 0; + } + } - path{ - fill:none; - pointer-events:all; - } + path{ + fill:none; + pointer-events:all; + } - &--path-selected{ - stroke: rgb(0,192,255) !important; - stroke-dasharray: 10,2; - animation: dash 1s linear infinite; - } + &--path-selected{ + stroke: rgb(0,192,255) !important; + stroke-dasharray: 10,2; + animation: dash 1s linear infinite; + } - &__label { - pointer-events: none; + &__label { + pointer-events: none; - > div{ - display: inline-block; - position: absolute; - } - } + > div{ + display: inline-block; + position: absolute; + } + } - &__point{ - fill: rgba(white,0.5); - } + &__point{ + fill: rgba(white,0.5); + } - &--point-selected{ - fill: rgb(0,192,255); - } + &--point-selected{ + fill: rgb(0,192,255); + } } \ No newline at end of file diff --git a/src/sass/defaults/_DefaultNodeWidget.scss b/src/sass/defaults/_DefaultNodeWidget.scss index 6de5c54..7ff4c4e 100644 --- a/src/sass/defaults/_DefaultNodeWidget.scss +++ b/src/sass/defaults/_DefaultNodeWidget.scss @@ -1,43 +1,43 @@ .srd-default-node { - background-color: rgb(30, 30, 30); - border-radius: 5px; - font-family: sans-serif; - color: white; - border: solid 2px black; - overflow: visible; - font-size: 11px; + background-color: rgb(30, 30, 30); + border-radius: 5px; + font-family: sans-serif; + color: white; + border: solid 2px black; + overflow: visible; + font-size: 11px; - &__title { - background: rgba(black, 0.3); - display: flex; - white-space: nowrap; - > * { - align-self: center; - } - .fa { - padding: 5px; - opacity: 0.2; - cursor: pointer; + &__title { + background: rgba(black, 0.3); + display: flex; + white-space: nowrap; + > * { + align-self: center; + } + .fa { + padding: 5px; + opacity: 0.2; + cursor: pointer; - &:hover { - opacity: 1.0; - } - } - } + &:hover { + opacity: 1.0; + } + } + } - &__name { - flex-grow: 1; - padding: 5px 5px; - } + &__name { + flex-grow: 1; + padding: 5px 5px; + } - &__ports { - display: flex; - background-image: linear-gradient(rgba(black, 0.1), rgba(black, 0.2)); - } + &__ports { + display: flex; + background-image: linear-gradient(rgba(black, 0.1), rgba(black, 0.2)); + } - &__in, &__out{ - flex-grow: 1; - display: flex; - flex-direction: column; - } + &__in, &__out{ + flex-grow: 1; + display: flex; + flex-direction: column; + } } \ No newline at end of file diff --git a/src/sass/defaults/_DefaultPortWidget.scss b/src/sass/defaults/_DefaultPortWidget.scss index 77abae1..94faad0 100644 --- a/src/sass/defaults/_DefaultPortWidget.scss +++ b/src/sass/defaults/_DefaultPortWidget.scss @@ -1,24 +1,24 @@ .srd-default-port{ - $p: &; + $p: &; - display: flex; - margin-top: 1px; + display: flex; + margin-top: 1px; - > * { - align-self: center; - } + > * { + align-self: center; + } - &__name { - padding: 0 5px; - } + &__name { + padding: 0 5px; + } - &--out{ - justify-content: flex-end; + &--out{ + justify-content: flex-end; - #{$p}__name { - justify-content: flex-end; - text-align: right; - } - } + #{$p}__name { + justify-content: flex-end; + text-align: right; + } + } } \ No newline at end of file diff --git a/src/widgets/DiagramWidget.tsx b/src/widgets/DiagramWidget.tsx index d749d1f..a41ae11 100644 --- a/src/widgets/DiagramWidget.tsx +++ b/src/widgets/DiagramWidget.tsx @@ -4,21 +4,19 @@ import * as _ from "lodash"; import { LinkLayerWidget } from "./layers/LinkLayerWidget"; import { NodeLayerWidget } from "./layers/NodeLayerWidget"; import { Toolkit } from "../Toolkit"; -import { BaseAction, MoveCanvasAction, MoveItemsAction, SelectingAction } from "../CanvasActions"; +import { BaseAction } from "../actions/BaseAction"; +import { MoveCanvasAction } from "../actions/MoveCanvasAction"; +import { MoveItemsAction } from "../actions/MoveItemsAction"; +import { SelectingAction } from "../actions/SelectingAction"; import { NodeModel } from "../models/NodeModel"; import { PointModel } from "../models/PointModel"; import { PortModel } from "../models/PortModel"; import { LinkModel } from "../models/LinkModel"; +import { SelectionModel } from "../models/SelectionModel"; import { BaseModel, BaseModelListener } from "../models/BaseModel"; import { BaseEntity } from "../BaseEntity"; import { BaseWidget, BaseWidgetProps } from "./BaseWidget"; -export interface SelectionModel { - model: BaseModel; - initialX: number; - initialY: number; -} - export interface DiagramProps extends BaseWidgetProps { diagramEngine: DiagramEngine; @@ -60,6 +58,8 @@ export class DiagramWidget extends BaseWidget { deleteKeys: [46, 8] }; + onKeyUpPointer: (this: Window, ev: KeyboardEvent) => void = null; + constructor(props: DiagramProps) { super("srd-diagram", props); this.onMouseMove = this.onMouseMove.bind(this); @@ -74,8 +74,6 @@ export class DiagramWidget extends BaseWidget { }; } - onKeyUpPointer: null; - componentWillUnmount() { this.props.diagramEngine.removeListener(this.state.diagramEngineListener); this.props.diagramEngine.setCanvas(null); @@ -445,9 +443,9 @@ export class DiagramWidget extends BaseWidget { //check if it is pinch gesture if (event.ctrlKey && scrollDelta % 1 !== 0) { /*Chrome and Firefox sends wheel event with deltaY that - have fractional part, also `ctrlKey` prop of the event is true - though ctrl isn't pressed - */ + have fractional part, also `ctrlKey` prop of the event is true + though ctrl isn't pressed + */ scrollDelta /= 3; } else { scrollDelta /= 60; diff --git a/src/widgets/layers/LinkLayerWidget.tsx b/src/widgets/layers/LinkLayerWidget.tsx index 4b4f75f..8fa5c0e 100644 --- a/src/widgets/layers/LinkLayerWidget.tsx +++ b/src/widgets/layers/LinkLayerWidget.tsx @@ -53,7 +53,9 @@ export class LinkLayerWidget extends BaseWidget link.sourcePort.updateCoords(portCoords); this.props.diagramEngine.linksThatHaveInitiallyRendered[link.id] = true; - } catch (ex) {} + } catch (ignore) { + /*noop*/ + } } if (link.targetPort !== null) { try { @@ -64,15 +66,16 @@ export class LinkLayerWidget extends BaseWidget link.targetPort.updateCoords(portCoords); this.props.diagramEngine.linksThatHaveInitiallyRendered[link.id] = true; - } catch (ex) {} + } catch (ignore) { + /*noop*/ + } } } //generate links var generatedLink = this.props.diagramEngine.generateWidgetForLink(link); if (!generatedLink) { - console.log("no link generated for type: " + link.getType()); - return null; + throw new Error(`no link generated for type: ${link.getType()}`); } return ( diff --git a/tests/e2e/E2EHelper.ts b/tests/e2e/E2EHelper.ts new file mode 100644 index 0000000..889734a --- /dev/null +++ b/tests/e2e/E2EHelper.ts @@ -0,0 +1,109 @@ +import { ElementHandle, Page } from "puppeteer"; +import { NodeModel } from "../../src/models/NodeModel"; +import { LinkModel } from "../../src/models/LinkModel"; +import * as _ from "lodash"; + +export class E2EElement { + helper: E2EHelper; + page: Page; + element: ElementHandle; + id: string; + + constructor(helper: E2EHelper, page: Page, element: ElementHandle, id: string) { + this.page = page; + this.element = element; + this.id = id; + this.helper = helper; + } +} + +export class E2ENode extends E2EElement { + async port(id: string): Promise { + return new E2EPort(this.helper, this.page, await this.element.$(`div[data-name="${id}"]`), id, this); + } + + async model(): Promise { + return await this.page.evaluate(id => { + return window["diagram_instance"] + .getDiagramModel() + .getNode(id) + .serialize(); + }, this.id); + } +} + +export class E2EPort extends E2EElement { + parent: E2ENode; + + constructor(helper: E2EHelper, page: Page, element: ElementHandle, id: string, parent: E2ENode) { + super(helper, page, element, id); + this.parent = parent; + } + + async link(port: E2EPort): Promise { + let currentLinks = _.flatMap((await this.parent.model()).ports, "links"); + + let bounds = await this.element.boundingBox(); + + // click on this port + this.page.mouse.move(bounds.x, bounds.y); + this.page.mouse.down(); + + let bounds2 = await port.element.boundingBox(); + + // drag to other port + this.page.mouse.move(bounds2.x, bounds2.y); + this.page.mouse.up(); + + // get the parent to get the link + return await this.helper.link( + _.difference(_.flatMap((await this.parent.model()).ports, "links"), currentLinks)[0] + ); + } +} + +export class E2ELink extends E2EElement { + async model(): Promise { + return await this.page.evaluate(id => { + return window["diagram_instance"] + .getDiagramModel() + .getLink(id) + .serialize(); + }, this.id); + } + + async exists(): Promise { + return await this.page.evaluate(id => { + return !!document.querySelector(`path[data-linkid="${id}"]`); + }, this.id); + } + + async select(): Promise { + const point = await this.page.evaluate(id => { + const path = document.querySelector(`path[data-linkid="${id}"]`) as SVGPathElement; + return path.getPointAtLength(path.getTotalLength() / 2); + }, this.id); + await this.page.keyboard.down("Shift"); + await this.page.mouse.move(point.x, point.y); + await this.page.mouse.down(); + await this.page.keyboard.up("Shift"); + } +} + +export class E2EHelper { + page: Page; + + constructor(page: Page) { + this.page = page; + } + + async link(id): Promise { + let selector = await this.page.waitForSelector(`path[data-linkid="${id}"]`); + return new E2ELink(this, this.page, selector, id); + } + + async node(id): Promise { + let selector = await this.page.waitForSelector(`div[data-nodeid="${id}"]`); + return new E2ENode(this, this.page, selector, id); + } +} diff --git a/tests/e2e/E2EHelper.tsx b/tests/e2e/E2EHelper.tsx deleted file mode 100644 index 72065a8..0000000 --- a/tests/e2e/E2EHelper.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import {ElementHandle, Page} from "puppeteer"; -import {NodeModel} from "../../src/models/NodeModel"; -import {LinkModel} from "../../src/models/LinkModel"; -import * as _ from "lodash"; - -export class E2EElement{ - helper: E2EHelper; - page: Page; - element: ElementHandle; - id: string; - - constructor(helper: E2EHelper,page: Page, element: ElementHandle, id: string) { - this.page = page; - this.element = element; - this.id = id; - this.helper = helper; - } -} - -export class E2ENode extends E2EElement{ - - async port(id: string): Promise{ - return new E2EPort(this.helper,this.page, await this.element.$('div[data-name="'+id+'"]'), id, this); - } - - async model(): Promise{ - return await this.page.evaluate((id) => { - return window['diagram_instance'].getDiagramModel().getNode(id).serialize(); - }, this.id) - } - -} - -export class E2EPort extends E2EElement{ - - parent: E2ENode; - - constructor(helper: E2EHelper,page: Page, element: ElementHandle, id: string, parent: E2ENode) { - super(helper,page, element, id); - this.parent = parent; - } - - - async link(port: E2EPort): Promise{ - - let currentLinks = _.flatMap((await this.parent.model()).ports, 'links'); - - let bounds = await this.element.boundingBox(); - - // click on this port - this.page.mouse.move(bounds.x, bounds.y); - this.page.mouse.down(); - - let bounds2 = await port.element.boundingBox(); - - // drag to other port - this.page.mouse.move(bounds2.x, bounds2.y); - this.page.mouse.up(); - - // get the parent to get the link - return await this.helper.link(_.difference(_.flatMap((await this.parent.model()).ports, 'links'), currentLinks)[0]); - } - -} - -export class E2ELink extends E2EElement{ - - async model(): Promise{ - return await this.page.evaluate((id) => { - return window['diagram_instance'].getDiagramModel().getLink(id).serialize(); - }, this.id) - } - - async exists():Promise{ - return await this.page.evaluate((id) => { - return !!document.querySelector('path[data-linkid="' + id + '"]'); - }, this.id); - } - - async select(): Promise{ - let point = await this.page.evaluate((id) => { - let path = (document.querySelector('path[data-linkid="' + id + '"]') as SVGPathElement); - let point = path.getPointAtLength(path.getTotalLength()/2); - return { - x: point.x, - y: point.y - } - }, this.id); - await this.page.keyboard.down('Shift'); - await this.page.mouse.move(point.x, point.y); - await this.page.mouse.down(); - await this.page.keyboard.up('Shift'); - } -} - - -export class E2EHelper { - - page: Page; - - constructor(page: Page) { - this.page = page; - } - - async link(id): Promise { - let selector = await this.page.waitForSelector('path[data-linkid="' + id + '"]'); - return new E2ELink(this,this.page, selector, id); - } - - async node(id): Promise { - let selector = await this.page.waitForSelector('div[data-nodeid="' + id + '"]'); - return new E2ENode(this,this.page, selector, id); - } - -} \ No newline at end of file diff --git a/tests/e2e/simple.test.tsx b/tests/e2e/simple.test.ts similarity index 62% rename from tests/e2e/simple.test.tsx rename to tests/e2e/simple.test.ts index 90f4c29..65bcd5d 100644 --- a/tests/e2e/simple.test.tsx +++ b/tests/e2e/simple.test.ts @@ -1,13 +1,13 @@ import "jest"; -import * as puppeteer from "puppeteer" -import {E2EHelper} from "./E2EHelper"; +import * as puppeteer from "puppeteer"; +import { E2EHelper } from "./E2EHelper"; var browser; async function itShould(demo: string, directive, test: (page: puppeteer.Page, helper: E2EHelper) => any) { it(directive, async () => { let page = await browser.newPage(); - await page.goto('file://' + __dirname + '/../../dist/e2e/' + demo + "/index.html"); + await page.goto("file://" + __dirname + "/../../dist/e2e/" + demo + "/index.html"); let helper = new E2EHelper(page); await test(page, helper); await page.close(); @@ -19,7 +19,7 @@ beforeAll(async () => { console.log("using CircleCI"); browser = await puppeteer.launch({ - args: ['--no-sandbox', '--disable-setuid-sandbox'] + args: ["--no-sandbox", "--disable-setuid-sandbox"] }); } else { browser = await puppeteer.launch({ @@ -32,31 +32,26 @@ afterAll(() => { browser.close(); }); - describe("simple test", async () => { - - itShould("demo-simple", 'should delete a link and create a new one', async (page, helper) => { - - + itShould("demo-simple", "should delete a link and create a new one", async (page, helper) => { // get the existing link - - let link = await helper.link('12'); + let link = await helper.link("12"); await expect(await link.exists()).toBeTruthy(); // remove it await link.select(); - await page.keyboard.press('Backspace'); + await page.keyboard.press("Del"); await expect(await link.exists()).toBeFalsy(); // create a new link - let node1 = await helper.node('6'); - let node2 = await helper.node('9'); + let node1 = await helper.node("6"); + let node2 = await helper.node("9"); - let port1 = await node1.port('7'); - let port2 = await node2.port('10'); + let port1 = await node1.port("7"); + let port2 = await node2.port("10"); let newlink = await port1.link(port2); await expect(await newlink.exists()).toBeTruthy(); }); -}) \ No newline at end of file +}); diff --git a/tests/routing/PathFinding.test.tsx b/tests/routing/PathFinding.test.tsx index 65c888b..592a205 100644 --- a/tests/routing/PathFinding.test.tsx +++ b/tests/routing/PathFinding.test.tsx @@ -1,47 +1,41 @@ import PathFinding from "../../src/routing/PathFinding"; -describe('calculating start and end points', () => { +describe("calculating start and end points", () => { + beforeEach(() => { + this.pathFinding = new PathFinding(null); + }); - beforeEach(() => { - this.pathFinding = new PathFinding(null); - }); - - test('return correct object for valid walkable input', () => { - const matrix = [ - [0, 0, 0, 0, 1, 1], - [0, 0, 0, 0, 1, 1], - [0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0], - [1, 1, 0, 0, 0, 0], - [1, 1, 0, 0, 0, 0], - ]; - const path = [[0, 5], [1, 4], [2, 3], [3, 2], [4, 1], [5, 0]]; + test("return correct object for valid walkable input", () => { + const matrix = [ + [0, 0, 0, 0, 1, 1], + [0, 0, 0, 0, 1, 1], + [0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0], + [1, 1, 0, 0, 0, 0], + [1, 1, 0, 0, 0, 0] + ]; + const path = [[0, 5], [1, 4], [2, 3], [3, 2], [4, 1], [5, 0]]; - const result = this.pathFinding.calculateLinkStartEndCoords(matrix, path); + const result = this.pathFinding.calculateLinkStartEndCoords(matrix, path); - expect(result.start).toEqual({ - x: 2, - y: 3, - }); - expect(result.end).toEqual({ - x: 3, - y: 2, - }); - expect(result.pathToStart).toEqual([[ 0, 5 ], [ 1, 4 ]]); - expect(result.pathToEnd).toEqual([[ 3, 2 ], [ 4, 1 ], [ 5, 0 ]]); - }); + expect(result.start).toEqual({ + x: 2, + y: 3 + }); + expect(result.end).toEqual({ + x: 3, + y: 2 + }); + expect(result.pathToStart).toEqual([[0, 5], [1, 4]]); + expect(result.pathToEnd).toEqual([[3, 2], [4, 1], [5, 0]]); + }); - test('undefined is returned when no walkable path exists', () => { - const matrix = [ - [0, 0, 1, 1], - [0, 0, 1, 1], - [1, 1, 0, 0], - [1, 1, 0, 0], - ]; - const path = [[0, 3], [1, 2], [2, 1], [3, 0]]; + test("undefined is returned when no walkable path exists", () => { + const matrix = [[0, 0, 1, 1], [0, 0, 1, 1], [1, 1, 0, 0], [1, 1, 0, 0]]; + const path = [[0, 3], [1, 2], [2, 1], [3, 0]]; - const result = this.pathFinding.calculateLinkStartEndCoords(matrix, path); + const result = this.pathFinding.calculateLinkStartEndCoords(matrix, path); - expect(result).toBeUndefined(); - }); -}); \ No newline at end of file + expect(result).toBeUndefined(); + }); +}); diff --git a/tests/snapshots/__snapshots__/storybook.test.tsx.snap b/tests/snapshots/__snapshots__/storybook.test.tsx.snap index 568b7f0..260984d 100644 --- a/tests/snapshots/__snapshots__/storybook.test.tsx.snap +++ b/tests/snapshots/__snapshots__/storybook.test.tsx.snap @@ -571,12 +571,12 @@ exports[`Storyshots Tests demos/demo-custom-node1/index.tsx 1`] = ` dangerouslySetInnerHTML={ Object { "__html": " - - - - - - ", + + + + + + ", } } height={150} diff --git a/tests/snapshots/storybook.test.tsx b/tests/snapshots/storybook.test.tsx index 34d16fe..68d4ff6 100644 --- a/tests/snapshots/storybook.test.tsx +++ b/tests/snapshots/storybook.test.tsx @@ -1,4 +1,4 @@ -import initStoryshots from '@storybook/addon-storyshots'; -import 'raf/polyfill'; +import initStoryshots from "@storybook/addon-storyshots"; +import "raf/polyfill"; -initStoryshots({ configPath: __dirname }); \ No newline at end of file +initStoryshots({ configPath: __dirname }); diff --git a/tests/snapshots/test_loader.tsx b/tests/snapshots/test_loader.tsx index 7c67579..30d40cf 100644 --- a/tests/snapshots/test_loader.tsx +++ b/tests/snapshots/test_loader.tsx @@ -1,5 +1,5 @@ import * as React from "react"; import { storiesOf, addDecorator } from "@storybook/react"; -import {Toolkit} from "../../src/Toolkit"; +import { Toolkit } from "../../src/Toolkit"; -Toolkit.TESTING = true; \ No newline at end of file +Toolkit.TESTING = true; diff --git a/tests/tslint.json b/tests/tslint.json new file mode 100644 index 0000000..a23574f --- /dev/null +++ b/tests/tslint.json @@ -0,0 +1,9 @@ +{ + "extends": [ + "../tslint.json" + ], + "rules": { + "no-console": false, + "max-classes-per-file": false + } +} \ No newline at end of file diff --git a/tslint.json b/tslint.json index fbc223b..4408b79 100644 --- a/tslint.json +++ b/tslint.json @@ -9,7 +9,11 @@ "comment-format": false, "max-line-length": false, "object-literal-sort-keys": false, - "quotemark": false, + "quotemark": [true, "double", "jsx-double"], + "arrow-parens": false, + "indent": [true, "tabs", 2], + "semicolon": false, + "object-literal-key-quotes": [true, "as-needed"], "no-var-keyword": false, "jsdoc-format": false, "prefer-const": false, diff --git a/webpack.config.js b/webpack.config.js index c12d2b1..7aa9489 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -14,7 +14,7 @@ if(process.env.NODE_ENV === 'production'){ } })); plugins.push(new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('production'), + 'process.env.NODE_ENV': 'production', })); } diff --git a/yarn.lock b/yarn.lock index 6dccaef..5bbd597 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2328,6 +2328,13 @@ create-react-class@^15.5.2, create-react-class@^15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" +cross-env@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.1.3.tgz#f8ae18faac87692b0a8b4d2f7000d4ec3a85dfd7" + dependencies: + cross-spawn "^5.1.0" + is-windows "^1.0.0" + cross-spawn@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" @@ -2335,7 +2342,7 @@ cross-spawn@^3.0.0: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^5.0.1: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -4306,7 +4313,7 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" -is-windows@^1.0.2: +is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"