diff --git a/.gitignore b/.gitignore
index 141b9b71..65989c34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ npm-debug.log
# Coverage #
/coverage/
+/xunit/
# Typing #
/src/typings/tsd/
@@ -64,4 +65,4 @@ testScreenshots
testResults
e2eResults
-e2e/dist
\ No newline at end of file
+e2e/dist
diff --git a/README.md b/README.md
index 90119b9c..822672c7 100644
--- a/README.md
+++ b/README.md
@@ -23,14 +23,13 @@ angular-tree-component supports angular 2 and above, and AoT compilation.
## Contributing
-run `npm run example:cli` and open [localhost:4200](http://localhost:4200) to test your code before submitting a pull request.
-
-Windows users - if it doesn't work try `npm run example:cli:win`.
+Run `npm run build` (`npm run build:win` for windows users) to build. Run `npm start:example-app` and open [localhost:4200](http://localhost:4200) to test your code before submitting a pull request.
To run tests locally - make sure port 4200 is available and run:
```
-$ npm run example:cli # Wait until webpack finishes and http://localhost:4200 is available
+$ npm run build # build:win for windows; wait until build finished
+$ npm run start:example-app # Wait until webpack finishes and http://localhost:4200 is available
$ npm run test:dev
```
@@ -39,4 +38,4 @@ Please check the issues / project before starting to work on a feature / bug to
## Contributors
This project exists thanks to all the people who contribute.
-
+
diff --git a/example/cli9/angular.json b/angular.json
similarity index 56%
rename from example/cli9/angular.json
rename to angular.json
index 941e6e65..8da2b841 100644
--- a/example/cli9/angular.json
+++ b/angular.json
@@ -3,32 +3,32 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
- "cli9": {
+ "example-app": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
- "root": "",
- "sourceRoot": "src",
+ "root": "projects/example-app",
+ "sourceRoot": "projects/example-app/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
- "outputPath": "dist/cli9",
- "index": "src/index.html",
- "main": "src/main.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "tsconfig.app.json",
- "aot": true,
+ "outputPath": "dist/example-app",
+ "index": "projects/example-app/src/index.html",
+ "main": "projects/example-app/src/main.ts",
+ "polyfills": "projects/example-app/src/polyfills.ts",
+ "tsConfig": "projects/example-app/tsconfig.app.json",
+ "aot": false,
"assets": [
- "src/favicon.ico",
- "src/assets"
+ "projects/example-app/src/favicon.ico",
+ "projects/example-app/src/assets"
],
"styles": [
- "src/styles.scss"
+ "projects/example-app/src/styles.scss"
],
"scripts": []
},
@@ -36,8 +36,8 @@
"production": {
"fileReplacements": [
{
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
+ "replace": "projects/example-app/src/environments/environment.ts",
+ "with": "projects/example-app/src/environments/environment.prod.ts"
}
],
"optimization": true,
@@ -45,6 +45,7 @@
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
+ "aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
@@ -66,33 +67,27 @@
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
- "browserTarget": "cli9:build"
+ "browserTarget": "example-app:build"
},
"configurations": {
"production": {
- "browserTarget": "cli9:build:production"
+ "browserTarget": "example-app:build:production"
}
}
},
- "extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "cli9:build"
- }
- },
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
- "main": "src/test.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "tsconfig.spec.json",
- "karmaConfig": "karma.conf.js",
+ "main": "projects/example-app/src/test.ts",
+ "karmaConfig": "projects/example-app/karma.conf.js",
+ "polyfills": "projects/example-app/src/polyfills.ts",
+ "tsConfig": "projects/example-app/tsconfig.spec.json",
"assets": [
- "src/favicon.ico",
- "src/assets"
+ "projects/example-app/src/favicon.ico",
+ "projects/example-app/src/assets"
],
"styles": [
- "src/styles.scss"
+ "projects/example-app/src/styles.scss"
],
"scripts": []
}
@@ -101,32 +96,15 @@
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
- "tsconfig.app.json",
- "tsconfig.spec.json",
- "e2e/tsconfig.json"
+ "projects/example-app/tsconfig.app.json",
+ "projects/example-app/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
- },
- "e2e": {
- "builder": "@angular-devkit/build-angular:protractor",
- "options": {
- "protractorConfig": "e2e/protractor.conf.js",
- "devServerTarget": "cli9:serve"
- },
- "configurations": {
- "production": {
- "devServerTarget": "cli9:serve:production"
- }
- }
}
}
- }
- },
- "defaultProject": "cli9",
- "cli": {
- "analytics": false
- }
-}
\ No newline at end of file
+ }},
+ "defaultProject": "example-app"
+}
diff --git a/atc-logo.png b/atc-logo.png
new file mode 100644
index 00000000..b101e61c
Binary files /dev/null and b/atc-logo.png differ
diff --git a/example/cli/.editorconfig b/example/cli/.editorconfig
deleted file mode 100644
index 6e87a003..00000000
--- a/example/cli/.editorconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# Editor configuration, see http://editorconfig.org
-root = true
-
-[*]
-charset = utf-8
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.md]
-max_line_length = off
-trim_trailing_whitespace = false
diff --git a/example/cli/README.md b/example/cli/README.md
deleted file mode 100644
index 17475a89..00000000
--- a/example/cli/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Cli6
-
-This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.1.
-
-## Development server
-
-Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
-
-## Code scaffolding
-
-Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
-
-## Build
-
-Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
-
-## Running unit tests
-
-Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
-
-## Running end-to-end tests
-
-Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
-
-## Further help
-
-To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
diff --git a/example/cli/dist/3rdpartylicenses.txt b/example/cli/dist/3rdpartylicenses.txt
deleted file mode 100644
index 525ed649..00000000
--- a/example/cli/dist/3rdpartylicenses.txt
+++ /dev/null
@@ -1,519 +0,0 @@
-core-js@2.5.6
-MIT
-Copyright (c) 2014-2018 Denis Pushkarev
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-zone.js@0.8.26
-MIT
-The MIT License
-
-Copyright (c) 2016-2018 Google, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-style-loader@0.21.0
-MIT
-Copyright JS Foundation and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-@angular/common@6.1.0
-MIT
-MIT
-
-@angular/core@6.1.0
-MIT
-MIT
-
-@angular/forms@6.1.0
-MIT
-MIT
-
-@angular/platform-browser@6.1.0
-MIT
-MIT
-
-@angular/router@6.1.0
-MIT
-MIT
-
-angular-tree-component@8.2.1
-MIT
-The MIT License (MIT)
-
-Copyright (c) 2016 500Tech LTD
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-lodash@4.17.10
-MIT
-Copyright JS Foundation and other contributors
API:
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ","import { Component, Input } from '@angular/core';\nimport { TreeNode, TreeModel, ITreeOptions } from 'angular-tree-component';\n\n@Component({\n selector: 'app-api',\n styles: [\n ],\n template: `\nAPI:
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n `\n})\nexport class ApiComponent {\n options: ITreeOptions = {\n\n };\n nodes = [\n {\n name: 'root1',\n children: [\n {\n name: 'child1'\n }, {\n name: 'child2'\n }\n ]\n },\n {\n name: 'root2',\n children: [\n {\n name: 'child2.1'\n }, {\n name: 'child2.2',\n children: [\n {\n id: 1001,\n name: 'subsub'\n }\n ]\n }\n ]\n }\n ];\n\n addNode(tree: any) {\n this.nodes[0].children.push({\n name: 'a new child'\n });\n tree.treeModel.update();\n }\n\n activateSubSub(tree: any) {\n // tree.treeModel.getNodeBy((node) => node.data.name === 'subsub')\n tree.treeModel.getNodeById(1001)\n .setActiveAndVisible();\n }\n\n activeNodes(treeModel: any) {\n console.log(treeModel.activeNodes);\n }\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\n\nimport { BasicTreeComponent } from './basictree/basictree.component';\nimport { FullTreeComponent } from './fulltree/fulltree.component';\nimport { TemplatesComponent } from './templates/templates.component';\nimport { FieldsComponent } from './fields/fields.component';\nimport { FilterComponent } from './filter/filter.component';\nimport { EmptyComponent } from './empty/empty.component';\nimport { RtlTreeComponent } from './rtl/rtl-tree.component';\nimport { AsyncTreeComponent } from './async/async.component';\nimport { SaveRestoreComponent } from './save-restore/save-restore.component';\nimport { CheckboxesComponent } from './checkboxes/checkboxes.component';\nimport { DragComponent } from './drag/drag.component';\nimport { VirtualscrollComponent } from './virtualscroll/virtualscroll.component';\nimport { ApiComponent } from './api/api.component';\nimport { ActionsComponent } from './actions/actions.component';\nimport { ScrollContainerComponent } from './scrollcontainer/scrollcontainer.component';\nimport { ContextmenuComponent } from './contextmenu/contextmenu.component';\nimport { DragOverStylingComponent } from './dragover-styling/dragover-styling.component';\nimport { DragOverStylingFullTreeComponent } from './dragover-styling/dragover-styling-full-tree.component';\n\nconst routes: Routes = [\n {\n path: '',\n component: FullTreeComponent\n },\n {\n path: 'basic',\n component: BasicTreeComponent\n },\n {\n path: 'fields',\n component: FieldsComponent\n },\n {\n path: 'templates',\n component: TemplatesComponent\n },\n {\n path: 'filter',\n component: FilterComponent\n },\n {\n path: 'empty',\n component: EmptyComponent\n },\n {\n path: 'rtl',\n component: RtlTreeComponent\n },\n {\n path: 'async',\n component: AsyncTreeComponent\n },\n {\n path: 'save-restore',\n component: SaveRestoreComponent\n },\n {\n path: 'checkboxes',\n component: CheckboxesComponent\n },\n {\n path: 'drag',\n component: DragComponent\n },\n {\n path: 'dragover-styling',\n component: DragOverStylingComponent\n },\n {\n path: 'dragover-styling-full-tree',\n component: DragOverStylingFullTreeComponent\n },\n {\n path: 'virtual',\n component: VirtualscrollComponent\n },\n {\n path: 'api',\n component: ApiComponent\n },\n {\n path: 'actions',\n component: ActionsComponent\n },\n {\n path: 'scroll-container',\n component: ScrollContainerComponent\n },\n {\n path: 'context-menu',\n component: ContextmenuComponent\n }\n];\n\n@NgModule({\n imports: [RouterModule.forRoot(routes, { useHash: true })],\n exports: [RouterModule]\n})\nexport class AppRoutingModule {}\n","\nKeys:
\n down | up | left | right | space | enter\n ","import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-basictree',\n template: `\nKeys:
\n down | up | left | right | space | enter\n `,\n styles: []\n})\nexport class BasicTreeComponent {\n nodes = [\n {\n name: 'root1',\n children: [\n { name: 'child1' },\n { name: 'child2' }\n ]\n },\n {\n name: 'root2',\n children: [\n { name: 'child2.1', children: [] },\n { name: 'child2.2', children: [\n {name: 'grandchild2.2.1'}\n ] }\n ]\n },\n { name: 'root3' },\n { name: 'root4', children: [] },\n { name: 'root5', children: null }\n ];\n}\n","\nKeys:
\n down | up | left | right | space | enter\n ","import { Component, HostListener } from '@angular/core';\nimport { ITreeOptions, TREE_ACTIONS, TreeNode, TreeModel } from 'angular-tree-component';\n\n@Component({\n selector: 'app-contextmenu',\n template: `\nKeys:
\n down | up | left | right | space | enter\n `,\n styles: [\n `.menu {\n position: absolute;\n background: rgba(255, 255, 255, 0.9);\n padding: 7px;\n border-radius: 5px;\n box-shadow: 0 0 2px 2px rgba(0,0,0,0.2);\n }`,\n `ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }`,\n `li {\n padding: 7px;\n border-radius: 3px;\n cursor: pointer;\n }`,\n `li:hover {\n background-color: aliceblue;\n }`,\n ]\n})\nexport class ContextmenuComponent {\n contextMenu: {node: TreeNode, x: number, y: number} = null;\n sourceNode: TreeNode = null;\n editNode: TreeNode = null;\n doCut = false;\n nodes = [\n {\n name: 'root1',\n children: [\n { name: 'child1' },\n { name: 'child2' }\n ]\n },\n {\n name: 'root2',\n children: [\n { name: 'child2.1', children: [] },\n { name: 'child2.2', children: [\n {name: 'grandchild2.2.1'}\n ] }\n ]\n },\n { name: 'root3' },\n { name: 'root4', children: [] },\n { name: 'root5', children: null }\n ];\n\n options: ITreeOptions = {\n actionMapping: {\n mouse: {\n contextMenu: (treeModel: TreeModel, treeNode: TreeNode, e: MouseEvent) => {\n e.preventDefault();\n if (this.contextMenu && treeNode === this.contextMenu.node) {\n return this.closeMenu();\n }\n this.contextMenu = {\n node: treeNode,\n x: e.pageX,\n y: e.pageY\n };\n },\n click: (treeModel: TreeModel, treeNode: TreeNode, e: MouseEvent) => {\n this.closeMenu();\n TREE_ACTIONS.TOGGLE_ACTIVE(treeModel, treeNode, e);\n }\n }\n }\n };\n\n closeMenu = () => {\n this.contextMenu = null;\n }\n\n edit = () => {\n this.editNode = this.contextMenu.node;\n this.closeMenu();\n }\n\n stopEdit = () => {\n this.editNode = null;\n }\n\n copy = () => {\n this.sourceNode = this.contextMenu.node;\n this.doCut = false;\n this.closeMenu();\n }\n\n cut = () => {\n this.sourceNode = this.contextMenu.node;\n this.doCut = true;\n this.closeMenu();\n }\n\n paste = () => {\n if (!this.canPaste()) {\n return;\n }\n this.doCut\n ? this.sourceNode.treeModel.moveNode(this.sourceNode, { parent: this.contextMenu.node, index: 0 })\n : this.sourceNode.treeModel.copyNode(this.sourceNode, { parent: this.contextMenu.node, index: 0 });\n\n this.sourceNode = null;\n this.closeMenu();\n }\n\n canPaste = () => {\n if (!this.sourceNode) {\n return false;\n }\n return this.sourceNode.treeModel.canMoveNode(this.sourceNode, { parent: this.contextMenu.node, index: 0 });\n }\n}\n\nfunction uuid() {\n return Math.floor(Math.random() * 10000000000000);\n}\n","\nKeys:
\n down | up | left | right | space | enter\nMouse:
\n click to select | shift+click to select multi\nAPI:
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ","import { Component, OnInit } from '@angular/core';\nimport {\n TreeNode,\n TreeModel,\n TREE_ACTIONS,\n KEYS,\n IActionMapping,\n ITreeOptions\n} from 'angular-tree-component';\n\nconst actionMapping: IActionMapping = {\n mouse: {\n contextMenu: (tree, node, $event) => {\n $event.preventDefault();\n alert(`context menu for ${node.data.name}`);\n },\n dblClick: (tree, node, $event) => {\n if (node.hasChildren) {\n TREE_ACTIONS.TOGGLE_EXPANDED(tree, node, $event);\n }\n },\n click: (tree, node, $event) => {\n $event.shiftKey\n ? TREE_ACTIONS.TOGGLE_ACTIVE_MULTI(tree, node, $event)\n : TREE_ACTIONS.TOGGLE_ACTIVE(tree, node, $event);\n }\n },\n keys: {\n [KEYS.ENTER]: (tree, node, $event) => alert(`This is ${node.data.name}`)\n }\n};\n\n@Component({\n selector: 'app-dragover-styling-fulltree',\n styles: [\n `\n button: {\n line-height: 24px;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);\n border: none;\n border-radius: 2px;\n background: #a3d9f5;\n cursor: pointer;\n margin: 0 3px;\n }\n `\n ],\n template: `\n \nKeys:
\n down | up | left | right | space | enter\nMouse:
\n click to select | shift+click to select multi\nAPI:
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n `\n})\nexport class DragOverStylingFullTreeComponent implements OnInit {\n nodes: any[];\n nodes2 = [{ name: 'root' }, { name: 'root2' }];\n asyncChildren = new Array(4).fill(null).map((item, n) => ({\n name: 'async child2.' + n,\n subTitle: 'async child ' + n,\n hasChildren: n < 5\n }));\n customTemplateStringOptions: ITreeOptions = {\n // displayField: 'subTitle',\n isExpandedField: 'expanded',\n idField: 'uuid',\n getChildren: this.getChildren.bind(this),\n actionMapping,\n nodeHeight: 23,\n allowDrag: node => {\n // console.log('allowDrag?');\n return true;\n },\n allowDrop: node => {\n // console.log('allowDrop?');\n return true;\n },\n allowDragoverStyling: false,\n useVirtualScroll: true,\n animateExpand: true\n };\n constructor() {}\n ngOnInit() {\n setTimeout(() => {\n this.nodes = [\n {\n expanded: true,\n name: 'root expanded',\n subTitle: 'the root',\n children: [\n {\n name: 'child2',\n subTitle: 'a bad child',\n hasChildren: false\n },\n {\n name: 'child2',\n subTitle: 'a bad child',\n hasChildren: false\n }\n ]\n },\n {\n name: 'root2',\n subTitle: 'the second root',\n children: [\n {\n name: 'child2.1',\n subTitle: 'new and improved',\n uuid: '11',\n hasChildren: false\n },\n {\n name: 'child2.2',\n subTitle: 'new and improved2',\n children: [\n {\n uuid: 1001,\n name: 'subsub',\n subTitle: 'subsub',\n hasChildren: false\n }\n ]\n }\n ]\n },\n {\n name: 'asyncroot',\n hasChildren: true\n }\n ];\n\n for (let i = 0; i < 1000; i++) {\n this.nodes.push({\n name: `rootDynamic${i}`,\n subTitle: `root created dynamically ${i}`,\n children: new Array(10).fill(null).map((item, n) => ({\n name: `rootChildDynamic${i}.${n}`,\n subTitle: `rootChildDynamicTitle${i}.${n}`\n }))\n });\n }\n }, 1);\n }\n\n getChildren(node: TreeNode) {\n return new Promise((resolve, reject) => {\n setTimeout(\n () =>\n resolve(\n this.asyncChildren.map(c => {\n return Object.assign({}, c, {\n hasChildren: node.level < 5\n });\n })\n ),\n 2000\n );\n });\n }\n\n addNode(tree: any) {\n this.nodes[0].children.push({\n name: 'a new child'\n });\n tree.treeModel.update();\n }\n\n childrenCount(node: TreeNode): string {\n return node && node.children ? `(${node.children.length})` : '';\n }\n\n filterNodes(text: string, tree: any) {\n tree.treeModel.filterNodes(text);\n }\n\n activateSubSub(tree: any) {\n // tree.treeModel.getNodeBy((node) => node.data.name === 'subsub')\n tree.treeModel.getNodeById(1001).setActiveAndVisible();\n }\n\n onEvent(event: any) {\n console.log(event);\n }\n\n onInitialized(tree: any) {\n // tree.treeModel.getNodeById('11').setActiveAndVisible();\n }\n\n go($event: any) {\n $event.stopPropagation();\n alert('this method is on the app component');\n }\n\n activeNodes(treeModel: TreeModel) {\n console.log(treeModel.activeNodes);\n }\n}\n","\nKeys:
\n down | up | left | right | space | enter\nMouse:
\n click to select | shift+click to select multi\nAPI:
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ","import { Component, Input, OnInit } from '@angular/core';\nimport { TreeNode, TreeModel, TREE_ACTIONS, KEYS, IActionMapping, ITreeOptions } from 'angular-tree-component';\n\nconst actionMapping: IActionMapping = {\n mouse: {\n contextMenu: (tree, node, $event) => {\n $event.preventDefault();\n alert(`context menu for ${node.data.name}`);\n },\n dblClick: (tree, node, $event) => {\n if (node.hasChildren) {\n TREE_ACTIONS.TOGGLE_EXPANDED(tree, node, $event);\n }\n },\n click: (tree, node, $event) => {\n $event.shiftKey\n ? TREE_ACTIONS.TOGGLE_ACTIVE_MULTI(tree, node, $event)\n : TREE_ACTIONS.TOGGLE_ACTIVE(tree, node, $event)\n }\n },\n keys: {\n [KEYS.ENTER]: (tree, node, $event) => alert(`This is ${node.data.name}`)\n }\n};\n\n@Component({\n selector: 'app-fulltree',\n styles: [\n `button: {\n line - height: 24px;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);\n border: none;\n border-radius: 2px;\n background: #A3D9F5;\n cursor: pointer;\n margin: 0 3px;\n }`\n ],\n template: `\n \nKeys:
\n down | up | left | right | space | enter\nMouse:
\n click to select | shift+click to select multi\nAPI:
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n `\n})\nexport class FullTreeComponent implements OnInit {\n nodes: any[];\n nodes2 = [{name: 'root'}, {name: 'root2'}];\n asyncChildren = new Array(4).fill(null).map((item, n) => ({\n name: 'async child2.' + n,\n subTitle: 'async child ' + n,\n hasChildren: n < 5\n }));\n customTemplateStringOptions: ITreeOptions = {\n // displayField: 'subTitle',\n isExpandedField: 'expanded',\n idField: 'uuid',\n getChildren: this.getChildren.bind(this),\n actionMapping,\n nodeHeight: 23,\n allowDrag: (node) => {\n // console.log('allowDrag?');\n return true;\n },\n allowDrop: (node) => {\n // console.log('allowDrop?');\n return true;\n },\n useVirtualScroll: true,\n animateExpand: true\n };\n constructor() {\n }\n ngOnInit() {\n setTimeout(() => {\n this.nodes = [\n {\n expanded: true,\n name: 'root expanded',\n subTitle: 'the root',\n children: [\n {\n name: 'child2',\n subTitle: 'a bad child',\n hasChildren: false\n },\n {\n name: 'child2',\n subTitle: 'a bad child',\n hasChildren: false\n }\n ]\n },\n {\n name: 'root2',\n subTitle: 'the second root',\n children: [\n {\n name: 'child2.1',\n subTitle: 'new and improved',\n uuid: '11',\n hasChildren: false\n }, {\n name: 'child2.2',\n subTitle: 'new and improved2',\n children: [\n {\n uuid: 1001,\n name: 'subsub',\n subTitle: 'subsub',\n hasChildren: false\n }\n ]\n }\n ]\n },\n {\n name: 'asyncroot',\n hasChildren: true\n }\n ];\n\n for (let i = 0; i < 1000; i++) {\n this.nodes.push({\n name: `rootDynamic${i}`,\n subTitle: `root created dynamically ${i}`,\n children: new Array(10).fill(null).map((item, n) => ({\n name: `rootChildDynamic${i}.${n}`,\n subTitle: `rootChildDynamicTitle${i}.${n}`\n }))\n });\n }\n }, 1);\n }\n\n getChildren(node: TreeNode) {\n return new Promise((resolve, reject) => {\n setTimeout(() => resolve(this.asyncChildren.map((c) => {\n return Object.assign({}, c, {\n hasChildren: node.level < 5\n });\n })), 2000);\n });\n }\n\n addNode(tree: any) {\n this.nodes[0].children.push({\n\n name: 'a new child'\n });\n tree.treeModel.update();\n }\n\n childrenCount(node: TreeNode): string {\n return node && node.children ? `(${node.children.length})` : '';\n }\n\n filterNodes(text: string, tree: any) {\n tree.treeModel.filterNodes(text);\n }\n\n activateSubSub(tree: any) {\n // tree.treeModel.getNodeBy((node) => node.data.name === 'subsub')\n tree.treeModel.getNodeById(1001)\n .setActiveAndVisible();\n }\n\n onEvent(event: any) {\n console.log(event);\n }\n\n onInitialized(tree: any) {\n // tree.treeModel.getNodeById('11').setActiveAndVisible();\n }\n\n go($event: any) {\n $event.stopPropagation();\n alert('this method is on the app component');\n }\n\n activeNodes(treeModel: TreeModel) {\n console.log(treeModel.activeNodes);\n }\n}\n","\n