Compare commits
103 Commits
Author | SHA1 | Date | |
---|---|---|---|
1a49bec3d4 | |||
64f9631946 | |||
84169a2c1e | |||
2a9ced5cbd | |||
ee5b88e19a | |||
608fcfd04e | |||
99c6502a65 | |||
28d27194be | |||
52f772676b | |||
8068751032 | |||
28f8de0da1 | |||
8cc4fb6f75 | |||
1196742e3b | |||
d398efe229 | |||
33e8fa7f5f | |||
b9833aa00b | |||
fc66124ea9 | |||
3f74a916d4 | |||
ff78754fd5 | |||
323255286b | |||
a9314b65f8 | |||
e5b3a101b8 | |||
8b2d20e8e9 | |||
26023fe884 | |||
9a2e06471c | |||
98f4ec1ce0 | |||
4d695274bb | |||
e5af89821d | |||
78b910504d | |||
93aabe0cbc | |||
27446f8d14 | |||
a026374e75 | |||
4f303921c6 | |||
dea6a5021d | |||
46c7c58402 | |||
0df3525bbf | |||
9667e2363c | |||
24ec96a2dd | |||
9844a2f88f | |||
0cdbeb98a2 | |||
dc40d3be6e | |||
2015917767 | |||
360d77d2ef | |||
75c3d8ed97 | |||
f94d59206e | |||
5b41f9789a | |||
ac84106dbc | |||
21f2267960 | |||
a9781943d5 | |||
6fc2f6f964 | |||
cd5773e58a | |||
f4bcb844dc | |||
24cf0f5623 | |||
5e02a3d757 | |||
42599dafb5 | |||
9c754f3444 | |||
6772f0cb16 | |||
2730ee6f6e | |||
de058e175b | |||
e9487c5ada | |||
035c846f85 | |||
80239229aa | |||
c12a7acb2c | |||
23bf5ad2f3 | |||
bed98624cc | |||
383c26dcef | |||
f505c101f7 | |||
ca071f79c2 | |||
20be9027fd | |||
63389812b5 | |||
6873432833 | |||
a7e3c24a27 | |||
358f50596c | |||
b61f5803fd | |||
c27f4aee57 | |||
5aa00a9f77 | |||
91075a60b1 | |||
57e590a704 | |||
8d3e571aa4 | |||
af5917b6e4 | |||
21ed977a55 | |||
f861364727 | |||
0ff4d534f4 | |||
ca408663a5 | |||
c96d66b34a | |||
896ca927f3 | |||
8253f8da38 | |||
cbb1c9ecfc | |||
1e8b6261dc | |||
f3b8a42d89 | |||
7812ff38cc | |||
d725363fe5 | |||
58d42558f7 | |||
aecbe32c6c | |||
35193043a2 | |||
7a229d8e3e | |||
ba1180786f | |||
535649f0a9 | |||
a4f7db62ba | |||
662aba4ec8 | |||
de07558349 | |||
b8253d365d | |||
05685af5c4 |
21
.github/workflows/main.yml
vendored
@ -2,7 +2,7 @@ name: Build
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '**'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
@ -10,19 +10,16 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node: [ 14, 16, 18 ]
|
|
||||||
name: Node ${{ matrix.node }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
- name: Setup Node ${{ matrix.node }}
|
- name: Setup node 14
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: 14.x
|
||||||
cache: 'yarn'
|
- uses: c-hive/gha-yarn-cache@v1
|
||||||
- name: Install JS dependencies
|
- name: Install JS dependencies
|
||||||
run: yarn install --frozen-lockfile --immutable
|
run: yarn install
|
||||||
- name: Test
|
- name: Test
|
||||||
run: yarn test
|
run: yarn test
|
||||||
|
1
.gitignore
vendored
@ -12,7 +12,6 @@
|
|||||||
/scripts/build
|
/scripts/build
|
||||||
/scripts/dist
|
/scripts/dist
|
||||||
/env
|
/env
|
||||||
/.angular
|
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
|
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"angular.enable-strict-mode-prompt": false
|
|
||||||
}
|
|
@ -3,11 +3,11 @@ __tests__
|
|||||||
node_modules/*/test
|
node_modules/*/test
|
||||||
node_modules/*/tests
|
node_modules/*/tests
|
||||||
powered-test
|
powered-test
|
||||||
#e2e
|
e2e
|
||||||
|
|
||||||
# asset directories
|
# asset directories
|
||||||
docs
|
docs
|
||||||
#doc
|
doc
|
||||||
website
|
website
|
||||||
images
|
images
|
||||||
|
|
||||||
|
477
angular.json
@ -1,234 +1,247 @@
|
|||||||
{
|
{
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
"gns3-web-ui": {
|
"gns3-web-ui": {
|
||||||
"root": "",
|
"root": "",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"architect": {
|
"architect": {
|
||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
"options": {
|
"options": {
|
||||||
"allowedCommonJsDependencies": [
|
"allowedCommonJsDependencies": [
|
||||||
"rxjs",
|
"rxjs",
|
||||||
"rxjs-compat",
|
"rxjs-compat",
|
||||||
"uuid",
|
"uuid",
|
||||||
"css-tree",
|
"css-tree",
|
||||||
"save-svg-as-png",
|
"save-svg-as-png",
|
||||||
"angular-draggable-droppable",
|
"angular-draggable-droppable",
|
||||||
"dom-set",
|
"dom-set",
|
||||||
"dom-plane",
|
"dom-plane",
|
||||||
"mousetrap",
|
"mousetrap",
|
||||||
"@mattlewis92/dom-autoscroller",
|
"@mattlewis92/dom-autoscroller",
|
||||||
"rxjs/Rx",
|
"rxjs/Rx",
|
||||||
"rxjs/add/operator/map",
|
"rxjs/add/operator/map",
|
||||||
"rxjs-compat/add/operator/map",
|
"rxjs-compat/add/operator/map",
|
||||||
"classnames",
|
"classnames",
|
||||||
"stylenames",
|
"stylenames",
|
||||||
"source-map-js",
|
"ipaddr.js"
|
||||||
"spark-md5",
|
],
|
||||||
"xterm",
|
"outputPath": "dist",
|
||||||
"xterm-addon-attach",
|
"index": "src/index.html",
|
||||||
"xterm-addon-fit"
|
"main": "src/main.ts",
|
||||||
],
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
"outputPath": "dist",
|
"polyfills": "src/polyfills.ts",
|
||||||
"index": "src/index.html",
|
"assets": [
|
||||||
"main": "src/main.ts",
|
"src/assets",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"src/favicon.ico",
|
||||||
"polyfills": "src/polyfills.ts",
|
"src/ReleaseNotes.txt"
|
||||||
"assets": [
|
],
|
||||||
"src/assets",
|
"styles": [
|
||||||
"src/favicon.ico",
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
"src/ReleaseNotes.txt"
|
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||||
],
|
"src/styles.scss",
|
||||||
"styles": [
|
"src/theme.scss"
|
||||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
],
|
||||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
"scripts": [],
|
||||||
"src/styles.scss",
|
"vendorChunk": true,
|
||||||
"src/theme.scss"
|
"extractLicenses": false,
|
||||||
],
|
"buildOptimizer": true,
|
||||||
"scripts": [],
|
"sourceMap": true,
|
||||||
"vendorChunk": true,
|
"optimization": false,
|
||||||
"extractLicenses": false,
|
"namedChunks": true,
|
||||||
"buildOptimizer": true,
|
"aot": true
|
||||||
"sourceMap": true,
|
},
|
||||||
"optimization": false,
|
"configurations": {
|
||||||
"namedChunks": true,
|
"production": {
|
||||||
"aot": true
|
"budgets": [
|
||||||
},
|
{
|
||||||
"configurations": {
|
"type": "anyComponentStyle",
|
||||||
"production": {
|
"maximumWarning": "6kb"
|
||||||
"budgets": [{
|
}
|
||||||
"type": "anyComponentStyle",
|
],
|
||||||
"maximumWarning": "6kb"
|
"optimization": true,
|
||||||
}],
|
"outputHashing": "all",
|
||||||
"optimization": true,
|
"sourceMap": {
|
||||||
"outputHashing": "all",
|
"hidden": true,
|
||||||
"sourceMap": {
|
"scripts": true,
|
||||||
"hidden": true,
|
"styles": false
|
||||||
"scripts": true,
|
},
|
||||||
"styles": false
|
"namedChunks": false,
|
||||||
},
|
"extractLicenses": true,
|
||||||
"namedChunks": false,
|
"vendorChunk": false,
|
||||||
"extractLicenses": true,
|
"buildOptimizer": true,
|
||||||
"vendorChunk": false,
|
"fileReplacements": [
|
||||||
"buildOptimizer": true,
|
{
|
||||||
"fileReplacements": [{
|
"replace": "src/environments/environment.ts",
|
||||||
"replace": "src/environments/environment.ts",
|
"with": "src/environments/environment.prod.ts"
|
||||||
"with": "src/environments/environment.prod.ts"
|
}
|
||||||
}]
|
]
|
||||||
},
|
},
|
||||||
"electronProd": {
|
"electronProd": {
|
||||||
"budgets": [{
|
"budgets": [
|
||||||
"type": "anyComponentStyle",
|
{
|
||||||
"maximumWarning": "6kb"
|
"type": "anyComponentStyle",
|
||||||
}],
|
"maximumWarning": "6kb"
|
||||||
"optimization": true,
|
}
|
||||||
"outputHashing": "all",
|
],
|
||||||
"sourceMap": false,
|
"optimization": true,
|
||||||
"namedChunks": false,
|
"outputHashing": "all",
|
||||||
"extractLicenses": true,
|
"sourceMap": false,
|
||||||
"vendorChunk": false,
|
"namedChunks": false,
|
||||||
"buildOptimizer": true,
|
"extractLicenses": true,
|
||||||
"fileReplacements": [{
|
"vendorChunk": false,
|
||||||
"replace": "src/environments/environment.ts",
|
"buildOptimizer": true,
|
||||||
"with": "src/environments/environment.electron.prod.ts"
|
"fileReplacements": [
|
||||||
}]
|
{
|
||||||
},
|
"replace": "src/environments/environment.ts",
|
||||||
"electronDev": {
|
"with": "src/environments/environment.electron.prod.ts"
|
||||||
"budgets": [{
|
}
|
||||||
"type": "anyComponentStyle",
|
]
|
||||||
"maximumWarning": "6kb"
|
},
|
||||||
}],
|
"electronDev": {
|
||||||
"fileReplacements": [{
|
"budgets": [
|
||||||
"replace": "src/environments/environment.ts",
|
{
|
||||||
"with": "src/environments/environment.electron.ts"
|
"type": "anyComponentStyle",
|
||||||
}]
|
"maximumWarning": "6kb"
|
||||||
},
|
}
|
||||||
"githubProd": {
|
],
|
||||||
"budgets": [{
|
"fileReplacements": [
|
||||||
"type": "anyComponentStyle",
|
{
|
||||||
"maximumWarning": "6kb"
|
"replace": "src/environments/environment.ts",
|
||||||
}],
|
"with": "src/environments/environment.electron.ts"
|
||||||
"optimization": true,
|
}
|
||||||
"outputHashing": "all",
|
]
|
||||||
"sourceMap": false,
|
},
|
||||||
"namedChunks": false,
|
"githubProd": {
|
||||||
"extractLicenses": true,
|
"budgets": [
|
||||||
"vendorChunk": false,
|
{
|
||||||
"buildOptimizer": true,
|
"type": "anyComponentStyle",
|
||||||
"fileReplacements": [{
|
"maximumWarning": "6kb"
|
||||||
"replace": "src/environments/environment.ts",
|
}
|
||||||
"with": "src/environments/environment.github.prod.ts"
|
],
|
||||||
}]
|
"optimization": true,
|
||||||
}
|
"outputHashing": "all",
|
||||||
}
|
"sourceMap": false,
|
||||||
},
|
"namedChunks": false,
|
||||||
"serve": {
|
"extractLicenses": true,
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"vendorChunk": false,
|
||||||
"options": {
|
"buildOptimizer": true,
|
||||||
"browserTarget": "gns3-web-ui:build"
|
"fileReplacements": [
|
||||||
},
|
{
|
||||||
"configurations": {
|
"replace": "src/environments/environment.ts",
|
||||||
"production": {
|
"with": "src/environments/environment.github.prod.ts"
|
||||||
"browserTarget": "gns3-web-ui:build:production"
|
}
|
||||||
},
|
]
|
||||||
"electronProd": {
|
}
|
||||||
"browserTarget": "gns3-web-ui:build:electronProd"
|
}
|
||||||
},
|
},
|
||||||
"electronDev": {
|
"serve": {
|
||||||
"browserTarget": "gns3-web-ui:build:electronDev"
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
},
|
"options": {
|
||||||
"githubProd": {
|
"browserTarget": "gns3-web-ui:build"
|
||||||
"browserTarget": "gns3-web-ui:build:githubProd"
|
},
|
||||||
}
|
"configurations": {
|
||||||
}
|
"production": {
|
||||||
},
|
"browserTarget": "gns3-web-ui:build:production"
|
||||||
"extract-i18n": {
|
},
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
"electronProd": {
|
||||||
"options": {
|
"browserTarget": "gns3-web-ui:build:electronProd"
|
||||||
"browserTarget": "gns3-web-ui:build"
|
},
|
||||||
}
|
"electronDev": {
|
||||||
},
|
"browserTarget": "gns3-web-ui:build:electronDev"
|
||||||
"test": {
|
},
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
"githubProd": {
|
||||||
"options": {
|
"browserTarget": "gns3-web-ui:build:githubProd"
|
||||||
"main": "src/test.ts",
|
}
|
||||||
"karmaConfig": "./karma.conf.js",
|
}
|
||||||
"polyfills": "src/polyfills.ts",
|
},
|
||||||
"tsConfig": "src/tsconfig.spec.json",
|
"extract-i18n": {
|
||||||
"scripts": [],
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
"styles": [
|
"options": {
|
||||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
"browserTarget": "gns3-web-ui:build"
|
||||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
}
|
||||||
"src/styles.scss",
|
},
|
||||||
"src/theme.scss"
|
"test": {
|
||||||
],
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
"sourceMap": false,
|
"options": {
|
||||||
"assets": [
|
"main": "src/test.ts",
|
||||||
"src/assets",
|
"karmaConfig": "./karma.conf.js",
|
||||||
"src/favicon.ico"
|
"polyfills": "src/polyfills.ts",
|
||||||
]
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
}
|
"scripts": [],
|
||||||
},
|
"styles": [
|
||||||
"lint": {
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||||
"options": {
|
"src/styles.scss",
|
||||||
"tsConfig": [
|
"src/theme.scss"
|
||||||
"src/tsconfig.app.json",
|
],
|
||||||
"src/tsconfig.spec.json"
|
"sourceMap": false,
|
||||||
],
|
"assets": [
|
||||||
"exclude": [
|
"src/assets",
|
||||||
"**/node_modules/**",
|
"src/favicon.ico"
|
||||||
"**/*.spec.ts"
|
]
|
||||||
]
|
}
|
||||||
}
|
},
|
||||||
}
|
"lint": {
|
||||||
},
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
"schematics": {
|
"options": {
|
||||||
"@schematics/angular:component": {
|
"tsConfig": [
|
||||||
"style": "scss"
|
"src/tsconfig.app.json",
|
||||||
}
|
"src/tsconfig.spec.json"
|
||||||
}
|
],
|
||||||
},
|
"exclude": [
|
||||||
"gns3-web-ui-e2e": {
|
"**/node_modules/**",
|
||||||
"root": "e2e",
|
"**/*.spec.ts"
|
||||||
"sourceRoot": "e2e",
|
]
|
||||||
"projectType": "application",
|
}
|
||||||
"architect": {
|
}
|
||||||
"e2e": {
|
},
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
"schematics": {
|
||||||
"options": {
|
"@schematics/angular:component": {
|
||||||
"protractorConfig": "./protractor.conf.js",
|
"style": "scss"
|
||||||
"devServerTarget": "gns3-web-ui:serve"
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint": {
|
"gns3-web-ui-e2e": {
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
"root": "e2e",
|
||||||
"options": {
|
"sourceRoot": "e2e",
|
||||||
"tsConfig": [
|
"projectType": "application",
|
||||||
"e2e/tsconfig.e2e.json"
|
"architect": {
|
||||||
],
|
"e2e": {
|
||||||
"exclude": [
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
"**/node_modules/**"
|
"options": {
|
||||||
]
|
"protractorConfig": "./protractor.conf.js",
|
||||||
}
|
"devServerTarget": "gns3-web-ui:serve"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
"lint": {
|
||||||
},
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
"schematics": {
|
"options": {
|
||||||
"@schematics/angular:component": {
|
"tsConfig": [
|
||||||
"prefix": "app",
|
"e2e/tsconfig.e2e.json"
|
||||||
"style": "scss"
|
],
|
||||||
},
|
"exclude": [
|
||||||
"@schematics/angular:directive": {
|
"**/node_modules/**"
|
||||||
"prefix": "app"
|
]
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"cli": {
|
}
|
||||||
"analytics": false
|
}
|
||||||
}
|
},
|
||||||
|
"defaultProject": "gns3-web-ui",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"prefix": "app",
|
||||||
|
"style": "scss"
|
||||||
|
},
|
||||||
|
"@schematics/angular:directive": {
|
||||||
|
"prefix": "app"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cli": {
|
||||||
|
"analytics": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
import { TestHelper } from './helpers/common.po';
|
|
||||||
import { ControllersPage } from './helpers/controller.po';
|
|
||||||
|
|
||||||
describe('Controllers page', () => {
|
|
||||||
let page: ControllersPage;
|
|
||||||
let helper: TestHelper;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new ControllersPage();
|
|
||||||
helper = new TestHelper();
|
|
||||||
});
|
|
||||||
|
|
||||||
xit('user should have possibility to add controller', async () => {
|
|
||||||
// arrange
|
|
||||||
page.maximizeWindow();
|
|
||||||
await page.navigateToControllersPage();
|
|
||||||
|
|
||||||
// act
|
|
||||||
let text = await page.getAddControllerNotificationText();
|
|
||||||
|
|
||||||
// assert
|
|
||||||
expect(text).toBe("We've discovered GNS3 controller on 127.0.0.1:3080, would you like to add to the list?");
|
|
||||||
});
|
|
||||||
|
|
||||||
it('user should see added controller in the list', async () => {
|
|
||||||
// arrange
|
|
||||||
page.maximizeWindow();
|
|
||||||
await page.navigateToControllersPage();
|
|
||||||
await page.clickAddController();
|
|
||||||
helper.sleep(1000);
|
|
||||||
|
|
||||||
// act
|
|
||||||
let firstRowOfControllersTable = await page.checkControllersTable();
|
|
||||||
let controllerData = [];
|
|
||||||
await helper.asyncForEach(firstRowOfControllersTable, async (element) => {
|
|
||||||
controllerData.push(await element.getText());
|
|
||||||
});
|
|
||||||
|
|
||||||
// assert
|
|
||||||
expect(controllerData).toContain('127.0.0.1');
|
|
||||||
expect(controllerData).toContain('3080');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,41 +1,41 @@
|
|||||||
import { browser, by } from 'protractor';
|
import { browser, by } from 'protractor';
|
||||||
import { TestHelper } from './common.po';
|
import { TestHelper } from './common.po';
|
||||||
|
|
||||||
export class ControllersPage {
|
export class ServersPage {
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
|
|
||||||
maximizeWindow() {
|
maximizeWindow() {
|
||||||
browser.driver.manage().window().maximize();
|
browser.driver.manage().window().maximize();
|
||||||
}
|
}
|
||||||
|
|
||||||
navigateToControllersPage() {
|
navigateToServersPage() {
|
||||||
return browser.get('/controllers');
|
return browser.get('/servers');
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddControllerNotificationText() {
|
getAddServerNotificationText() {
|
||||||
return browser.driver.findElement(by.className('mat-card-content')).getText();
|
return browser.driver.findElement(by.className('mat-card-content')).getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickAddController() {
|
async clickAddServer() {
|
||||||
let controllerTable = await this.checkControllersTable();
|
let serversTable = await this.checkServersTable();
|
||||||
if (controllerTable.length === 0) {
|
if (serversTable.length === 0) {
|
||||||
let buttons = await browser.driver.findElements(by.className('mat-button mat-button-base'));
|
let buttons = await browser.driver.findElements(by.className('mat-button mat-button-base'));
|
||||||
await buttons[3].click();
|
await buttons[3].click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkControllersTable() {
|
checkServersTable() {
|
||||||
return browser.driver.findElements(by.css('mat-cell'));
|
return browser.driver.findElements(by.css('mat-cell'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async navigateToControllerProjects() {
|
async navigateToServerProjects() {
|
||||||
this.helper.sleep(2000);
|
this.helper.sleep(2000);
|
||||||
let hyperlinks = await browser.driver.findElements(by.css('a.table-link'));
|
let hyperlinks = await browser.driver.findElements(by.css('a.table-link'));
|
||||||
let controllerLink;
|
let serverLink;
|
||||||
await this.helper.asyncForEach(hyperlinks, async (element) => {
|
await this.helper.asyncForEach(hyperlinks, async (element) => {
|
||||||
let text = await element.getText();
|
let text = await element.getText();
|
||||||
if (text === '127.0.0.1') controllerLink = element;
|
if (text === '127.0.0.1') serverLink = element;
|
||||||
});
|
});
|
||||||
await controllerLink.click();
|
await serverLink.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,24 +1,24 @@
|
|||||||
import { TestHelper } from './helpers/common.po';
|
import { TestHelper } from './helpers/common.po';
|
||||||
import { ProjectMapPage } from './helpers/project-map.po';
|
import { ProjectMapPage } from './helpers/project-map.po';
|
||||||
import { ProjectsPage } from './helpers/project.po';
|
import { ProjectsPage } from './helpers/project.po';
|
||||||
import { ControllersPage } from './helpers/controller.po';
|
import { ServersPage } from './helpers/server.po';
|
||||||
|
|
||||||
describe('Project map page', () => {
|
describe('Project map page', () => {
|
||||||
let controllersPage: ControllersPage;
|
let serversPage: ServersPage;
|
||||||
let projectsPage: ProjectsPage;
|
let projectsPage: ProjectsPage;
|
||||||
let projectMapPage: ProjectMapPage;
|
let projectMapPage: ProjectMapPage;
|
||||||
let helper: TestHelper;
|
let helper: TestHelper;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
controllersPage = new ControllersPage();
|
serversPage = new ServersPage();
|
||||||
projectsPage = new ProjectsPage();
|
projectsPage = new ProjectsPage();
|
||||||
projectMapPage = new ProjectMapPage();
|
projectMapPage = new ProjectMapPage();
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
|
|
||||||
controllersPage.maximizeWindow();
|
serversPage.maximizeWindow();
|
||||||
await controllersPage.navigateToControllersPage();
|
await serversPage.navigateToServersPage();
|
||||||
await controllersPage.clickAddController();
|
await serversPage.clickAddServer();
|
||||||
await controllersPage.navigateToControllerProjects();
|
await serversPage.navigateToServerProjects();
|
||||||
await projectsPage.openAddProjectDialog();
|
await projectsPage.openAddProjectDialog();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
await projectsPage.createProject();
|
await projectsPage.createProject();
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import { TestHelper } from './helpers/common.po';
|
import { TestHelper } from './helpers/common.po';
|
||||||
import { ProjectsPage } from './helpers/project.po';
|
import { ProjectsPage } from './helpers/project.po';
|
||||||
import { ControllersPage } from './helpers/controller.po';
|
import { ServersPage } from './helpers/server.po';
|
||||||
|
|
||||||
describe('Projects page', () => {
|
describe('Projects page', () => {
|
||||||
let controllersPage: ControllersPage;
|
let serversPage: ServersPage;
|
||||||
let projectsPage: ProjectsPage;
|
let projectsPage: ProjectsPage;
|
||||||
let helper: TestHelper;
|
let helper: TestHelper;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
controllersPage = new ControllersPage();
|
serversPage = new ServersPage();
|
||||||
projectsPage = new ProjectsPage();
|
projectsPage = new ProjectsPage();
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('user should have possibility to create new project', async () => {
|
it('user should have possibility to create new project', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
controllersPage.maximizeWindow();
|
serversPage.maximizeWindow();
|
||||||
await controllersPage.navigateToControllersPage();
|
await serversPage.navigateToServersPage();
|
||||||
await controllersPage.clickAddController();
|
await serversPage.clickAddServer();
|
||||||
await controllersPage.navigateToControllerProjects();
|
await serversPage.navigateToServerProjects();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
@ -28,6 +28,6 @@ describe('Projects page', () => {
|
|||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
expect(helper.getCurrentUrl()).toMatch('controller/1/project/');
|
expect(helper.getCurrentUrl()).toMatch('server/1/project/');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
43
e2e/servers.e2e-spec.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { TestHelper } from './helpers/common.po';
|
||||||
|
import { ServersPage } from './helpers/server.po';
|
||||||
|
|
||||||
|
describe('Servers page', () => {
|
||||||
|
let page: ServersPage;
|
||||||
|
let helper: TestHelper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new ServersPage();
|
||||||
|
helper = new TestHelper();
|
||||||
|
});
|
||||||
|
|
||||||
|
xit('user should have possibility to add server', async () => {
|
||||||
|
// arrange
|
||||||
|
page.maximizeWindow();
|
||||||
|
await page.navigateToServersPage();
|
||||||
|
|
||||||
|
// act
|
||||||
|
let text = await page.getAddServerNotificationText();
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(text).toBe("We've discovered GNS3 server on 127.0.0.1:3080, would you like to add to the list?");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('user should see added server in the list', async () => {
|
||||||
|
// arrange
|
||||||
|
page.maximizeWindow();
|
||||||
|
await page.navigateToServersPage();
|
||||||
|
await page.clickAddServer();
|
||||||
|
helper.sleep(1000);
|
||||||
|
|
||||||
|
// act
|
||||||
|
let firstRowOfServersTable = await page.checkServersTable();
|
||||||
|
let serverData = [];
|
||||||
|
await helper.asyncForEach(firstRowOfServersTable, async (element) => {
|
||||||
|
serverData.push(await element.getText());
|
||||||
|
});
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(serverData).toContain('127.0.0.1');
|
||||||
|
expect(serverData).toContain('3080');
|
||||||
|
});
|
||||||
|
});
|
@ -15,7 +15,7 @@ files:
|
|||||||
- renderer.js
|
- renderer.js
|
||||||
- sentry.js
|
- sentry.js
|
||||||
- installed-software.js
|
- installed-software.js
|
||||||
- local-controller.js
|
- local-server.js
|
||||||
- console-executor.js
|
- console-executor.js
|
||||||
- package.json
|
- package.json
|
||||||
|
|
||||||
|
@ -19,13 +19,13 @@ module.exports = function (config) {
|
|||||||
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
|
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
|
||||||
fixWebpackSourcePaths: true
|
fixWebpackSourcePaths: true
|
||||||
},
|
},
|
||||||
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
reporters: ['progress', 'kjhtml'],
|
||||||
port: 9876,
|
port: 9876,
|
||||||
colors: true,
|
colors: true,
|
||||||
logLevel: config.LOG_INFO,
|
logLevel: config.LOG_INFO,
|
||||||
autoWatch: true,
|
autoWatch: true,
|
||||||
browsers: ['ChromeHeadless'],
|
browsers: ['Chrome'],
|
||||||
singleRun: true
|
singleRun: true
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -8,9 +8,9 @@ const { app } = require('electron')
|
|||||||
|
|
||||||
const isWin = /^win/.test(process.platform);
|
const isWin = /^win/.test(process.platform);
|
||||||
|
|
||||||
let runningControllers = {};
|
let runningServers = {};
|
||||||
|
|
||||||
exports.getLocalControllerPath = async () => {
|
exports.getLocalServerPath = async () => {
|
||||||
let binary = isWin ? 'gns3server.exe': 'gns3server';
|
let binary = isWin ? 'gns3server.exe': 'gns3server';
|
||||||
return findBinary('exe.', binary);
|
return findBinary('exe.', binary);
|
||||||
}
|
}
|
||||||
@ -20,27 +20,27 @@ exports.getUbridgePath = async () => {
|
|||||||
return findBinary('ubridge', binary);
|
return findBinary('ubridge', binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.startLocalController = async (controller) => {
|
exports.startLocalServer = async (server) => {
|
||||||
return await run(controller, {
|
return await run(server, {
|
||||||
logStdout: true
|
logStdout: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.stopLocalController = async (controller) => {
|
exports.stopLocalServer = async (server) => {
|
||||||
return await stop(controller.name);
|
return await stop(server.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getRunningControllers = () => {
|
exports.getRunningServers = () => {
|
||||||
return Object.keys(runningControllers);
|
return Object.keys(runningServers);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.stopAllLocalControllers = async () => {
|
exports.stopAllLocalServers = async () => {
|
||||||
return await stopAll();
|
return await stopAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findBinary(binaryDirectory, filename) {
|
async function findBinary(binaryDirectory, filename) {
|
||||||
const lookupDirectories = [
|
const lookupDirectories = [
|
||||||
__dirname,
|
__dirname,
|
||||||
path.dirname(app.getPath('exe'))
|
path.dirname(app.getPath('exe'))
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ async function findBinaryInDirectory(baseDirectory, binaryDirectory, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const files = fs.readdirSync(distDirectory);
|
const files = fs.readdirSync(distDirectory);
|
||||||
|
|
||||||
let binaryPath = null;
|
let binaryPath = null;
|
||||||
|
|
||||||
files.forEach((directory) => {
|
files.forEach((directory) => {
|
||||||
@ -77,33 +77,33 @@ async function findBinaryInDirectory(baseDirectory, binaryDirectory, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getControllerArguments(controller, overrides, configPath) {
|
function getServerArguments(server, overrides, configPath) {
|
||||||
let controllerArguments = [];
|
let serverArguments = [];
|
||||||
if(controller.host) {
|
if(server.host) {
|
||||||
controllerArguments.push('--host');
|
serverArguments.push('--host');
|
||||||
controllerArguments.push(controller.host);
|
serverArguments.push(server.host);
|
||||||
}
|
}
|
||||||
if(controller.port) {
|
if(server.port) {
|
||||||
controllerArguments.push('--port');
|
serverArguments.push('--port');
|
||||||
controllerArguments.push(controller.port);
|
serverArguments.push(server.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
controllerArguments.push('--local');
|
serverArguments.push('--local');
|
||||||
|
|
||||||
if(configPath) {
|
if(configPath) {
|
||||||
controllerArguments.push('--config');
|
serverArguments.push('--config');
|
||||||
controllerArguments.push(configPath);
|
serverArguments.push(configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return controllerArguments;
|
return serverArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannelForController(controller) {
|
function getChannelForServer(server) {
|
||||||
return `local-controller-run-${controller.name}`;
|
return `local-server-run-${server.name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function notifyStatus(status) {
|
function notifyStatus(status) {
|
||||||
ipcMain.emit('local-controller-status-events', status);
|
ipcMain.emit('local-server-status-events', status);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterOutput(line) {
|
function filterOutput(line) {
|
||||||
@ -120,44 +120,44 @@ function filterOutput(line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function stopAll() {
|
async function stopAll() {
|
||||||
for(var controllerName in runningControllers) {
|
for(var serverName in runningServers) {
|
||||||
let result, error = await stop(controllerName);
|
let result, error = await stop(serverName);
|
||||||
}
|
}
|
||||||
console.log(`Stopped all controllers`);
|
console.log(`Stopped all servers`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stop(controllerName) {
|
async function stop(serverName) {
|
||||||
let pid = undefined;
|
let pid = undefined;
|
||||||
|
|
||||||
const runningController = runningControllers[controllerName];
|
const runningServer = runningServers[serverName];
|
||||||
|
|
||||||
if(runningController !== undefined && runningController.process) {
|
if(runningServer !== undefined && runningServer.process) {
|
||||||
pid = runningController.process.pid;
|
pid = runningServer.process.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Stopping '${controllerName}' with PID='${pid}'`);
|
console.log(`Stopping '${serverName}' with PID='${pid}'`);
|
||||||
|
|
||||||
const stopped = new Promise((resolve, reject) => {
|
const stopped = new Promise((resolve, reject) => {
|
||||||
if(pid === undefined) {
|
if(pid === undefined) {
|
||||||
resolve(`Controller '${controllerName} is already stopped`);
|
resolve(`Server '${serverName} is already stopped`);
|
||||||
delete runningControllers[controllerName];
|
delete runningServers[serverName];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kill(pid, (error) => {
|
kill(pid, (error) => {
|
||||||
if(error) {
|
if(error) {
|
||||||
console.error(`Error occured during stopping '${controllerName}' with PID='${pid}'`);
|
console.error(`Error occured during stopping '${serverName}' with PID='${pid}'`);
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delete runningControllers[controllerName];
|
delete runningServers[serverName];
|
||||||
console.log(`Stopped '${controllerName}' with PID='${pid}'`);
|
console.log(`Stopped '${serverName}' with PID='${pid}'`);
|
||||||
resolve(`Stopped '${controllerName}' with PID='${pid}'`);
|
resolve(`Stopped '${serverName}' with PID='${pid}'`);
|
||||||
|
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
controllerName: controllerName,
|
serverName: serverName,
|
||||||
status: 'stopped',
|
status: 'stopped',
|
||||||
message: `Controller '${controllerName}' stopped'`
|
message: `Server '${serverName}' stopped'`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -166,11 +166,11 @@ async function stop(controllerName) {
|
|||||||
return stopped;
|
return stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getIniFile(controller) {
|
async function getIniFile(server) {
|
||||||
return path.join(app.getPath('userData'), `gns3_controller_${controller.id}.ini`);
|
return path.join(app.getPath('userData'), `gns3_server_${server.id}.ini`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function configure(configPath, controller) {
|
async function configure(configPath, server) {
|
||||||
if(!fs.existsSync(configPath)) {
|
if(!fs.existsSync(configPath)) {
|
||||||
fs.closeSync(fs.openSync(configPath, 'w'));
|
fs.closeSync(fs.openSync(configPath, 'w'));
|
||||||
console.log(`Configuration file '${configPath}' has been created.`);
|
console.log(`Configuration file '${configPath}' has been created.`);
|
||||||
@ -178,20 +178,20 @@ async function configure(configPath, controller) {
|
|||||||
|
|
||||||
var config = ini.parse(fs.readFileSync(configPath, 'utf-8'));
|
var config = ini.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||||
|
|
||||||
if(controller.path) {
|
if(server.path) {
|
||||||
config.path = controller.path;
|
config.path = server.path;
|
||||||
}
|
}
|
||||||
if(controller.host) {
|
if(server.host) {
|
||||||
config.host = controller.host;
|
config.host = server.host;
|
||||||
}
|
}
|
||||||
if(controller.port) {
|
if(server.port) {
|
||||||
config.port = controller.port;
|
config.port = server.port;
|
||||||
}
|
}
|
||||||
if(controller.ubridge_path) {
|
if(server.ubridge_path) {
|
||||||
config.ubridge_path = controller.ubridge_path;
|
config.ubridge_path = server.ubridge_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(configPath, ini.stringify(config, { section: 'Controller' }));
|
fs.writeFileSync(configPath, ini.stringify(config, { section: 'Server' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setPATHEnv() {
|
async function setPATHEnv() {
|
||||||
@ -216,7 +216,7 @@ async function setPATHEnv() {
|
|||||||
process.env.PATH = extra.join(";");
|
process.env.PATH = extra.join(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run(controller, options) {
|
async function run(server, options) {
|
||||||
if(!options) {
|
if(!options) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
@ -226,34 +226,34 @@ async function run(controller, options) {
|
|||||||
|
|
||||||
console.log(`Configuring`);
|
console.log(`Configuring`);
|
||||||
|
|
||||||
const configPath = await getIniFile(controller);
|
const configPath = await getIniFile(server);
|
||||||
await configure(configPath, controller);
|
await configure(configPath, server);
|
||||||
|
|
||||||
console.log(`Setting up PATH`);
|
console.log(`Setting up PATH`);
|
||||||
await setPATHEnv();
|
await setPATHEnv();
|
||||||
|
|
||||||
console.log(`Running '${controller.path}'`);
|
console.log(`Running '${server.path}'`);
|
||||||
|
|
||||||
let controllerProcess = spawn(controller.path, getControllerArguments(controller, {}, configPath));
|
let serverProcess = spawn(server.path, getServerArguments(server, {}, configPath));
|
||||||
|
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
controllerName: controller.name,
|
serverName: server.name,
|
||||||
status: 'started',
|
status: 'started',
|
||||||
message: `Controller '${controller.name}' started'`
|
message: `Server '${server.name}' started'`
|
||||||
});
|
});
|
||||||
|
|
||||||
runningControllers[controller.name] = {
|
runningServers[server.name] = {
|
||||||
process: controllerProcess
|
process: serverProcess
|
||||||
};
|
};
|
||||||
|
|
||||||
controllerProcess.stdout.on('data', function(data) {
|
serverProcess.stdout.on('data', function(data) {
|
||||||
const line = data.toString();
|
const line = data.toString();
|
||||||
const { isCritical, errorMessage } = filterOutput(line);
|
const { isCritical, errorMessage } = filterOutput(line);
|
||||||
if(isCritical) {
|
if(isCritical) {
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
controllerName: controller.name,
|
serverName: server.name,
|
||||||
status: 'stderr',
|
status: 'stderr',
|
||||||
message: `Controller reported error: '${errorMessage}`
|
message: `Server reported error: '${errorMessage}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,25 +262,25 @@ async function run(controller, options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
controllerProcess.stderr.on('data', function(data) {
|
serverProcess.stderr.on('data', function(data) {
|
||||||
if(logSterr) {
|
if(logSterr) {
|
||||||
console.log(data.toString());
|
console.log(data.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
controllerProcess.on('exit', (code, signal) => {
|
serverProcess.on('exit', (code, signal) => {
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
controllerName: controller.name,
|
serverName: server.name,
|
||||||
status: 'errored',
|
status: 'errored',
|
||||||
message: `controller '${controller.name}' has exited with status='${code}'`
|
message: `Server '${server.name}' has exited with status='${code}'`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
controllerProcess.on('error', (err) => {
|
serverProcess.on('error', (err) => {
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
controllerName: controller.name,
|
serverName: server.name,
|
||||||
status: 'errored',
|
status: 'errored',
|
||||||
message: `Controller errored: '${err}`
|
message: `Server errored: '${err}`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -297,9 +297,9 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ipcMain) {
|
if(ipcMain) {
|
||||||
ipcMain.on('local-controller-run', async function (event, controller) {
|
ipcMain.on('local-server-run', async function (event, server) {
|
||||||
const responseChannel = getChannelForController();
|
const responseChannel = getChannelForServer();
|
||||||
await run(controller);
|
await run(server);
|
||||||
event.sender.send(responseChannel, {
|
event.sender.send(responseChannel, {
|
||||||
success: true
|
success: true
|
||||||
});
|
});
|
||||||
@ -318,4 +318,4 @@ if (require.main === module) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
main();
|
main();
|
||||||
}
|
}
|
100
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gns3-web-ui",
|
"name": "gns3-web-ui",
|
||||||
"version": "3.0.0a4",
|
"version": "2.2.53",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "GNS3 Technology Inc.",
|
"name": "GNS3 Technology Inc.",
|
||||||
"email": "developers@gns3.com"
|
"email": "developers@gns3.com"
|
||||||
@ -36,100 +36,98 @@
|
|||||||
"generate-licenses-file": "yarn license-checker --production --csv --out licenses.csv",
|
"generate-licenses-file": "yarn license-checker --production --csv --out licenses.csv",
|
||||||
"prebuildforelectron": "node set-variables-in-env.js --set src/environments/environment.electron.prod.ts",
|
"prebuildforelectron": "node set-variables-in-env.js --set src/environments/environment.electron.prod.ts",
|
||||||
"postbuildforelectron": "node set-variables-in-env.js --unset src/environments/environment.electron.prod.ts",
|
"postbuildforelectron": "node set-variables-in-env.js --unset src/environments/environment.electron.prod.ts",
|
||||||
"postinstall": "ngcc --properties es2020 browser module main --first-only --create-ivy-entry-points --tsconfig \"./src/tsconfig.app.json\" && ngcc --properties es2020 browser module main --first-only --create-ivy-entry-points --tsconfig \"./src/tsconfig.app.json\"",
|
"postinstall": "ngcc --properties es5 browser module main --first-only --create-ivy-entry-points && ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points",
|
||||||
"snyk-protect": "snyk-protect",
|
"snyk-protect": "snyk protect",
|
||||||
"prepare": "yarn run snyk-protect"
|
"prepare": "yarn run snyk-protect"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^14.3.0",
|
"@angular/animations": "^12.2.12",
|
||||||
"@angular/cdk": "^14.2.7",
|
"@angular/cdk": "^12.2.12",
|
||||||
"@angular/common": "^14.3.0",
|
"@angular/common": "^12.2.12",
|
||||||
"@angular/compiler": "^14.3.0",
|
"@angular/compiler": "^12.2.12",
|
||||||
"@angular/core": "^14.3.0",
|
"@angular/core": "^12.2.12",
|
||||||
"@angular/forms": "^14.3.0",
|
"@angular/forms": "^12.2.12",
|
||||||
"@angular/material": "^14.2.7",
|
"@angular/material": "^12.2.12",
|
||||||
"@angular/platform-browser": "^14.3.0",
|
"@angular/platform-browser": "^12.2.12",
|
||||||
"@angular/platform-browser-dynamic": "^14.3.0",
|
"@angular/platform-browser-dynamic": "^12.2.12",
|
||||||
"@angular/router": "^14.3.0",
|
"@angular/router": "^12.2.12",
|
||||||
"@sentry/browser": "^6.14.1",
|
"@sentry/browser": "^6.14.1",
|
||||||
"@snyk/protect": "^1.972.0",
|
|
||||||
"@types/jest": "^27.0.2",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/mocha": "^9.1.1",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/react": "^17.0.34",
|
"@types/react": "^17.0.34",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"angular-draggable-droppable": "^6.1.0",
|
"angular-draggable-droppable": "^5.0.0",
|
||||||
"angular-resizable-element": "^3.4.0",
|
"angular-resizable-element": "^3.4.0",
|
||||||
"autoprefixer": "10.4.5",
|
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
"core-js": "^3.22.3",
|
"core-js": "^3.19.1",
|
||||||
"css-tree": "^2.1.0",
|
"css-tree": "^1.1.3",
|
||||||
"d3-ng2-service": "^2.2.0",
|
"d3-ng2-service": "^2.2.0",
|
||||||
"eev": "^0.1.5",
|
"eev": "^0.1.5",
|
||||||
"ini": "^3.0.0",
|
"ini": "^2.0.0",
|
||||||
"marked": "^4.0.14",
|
"ipaddr.js": "^2.1.0",
|
||||||
"material-design-icons": "^3.0.1",
|
"material-design-icons": "^3.0.1",
|
||||||
"mousetrap": "^1.6.5",
|
"mousetrap": "^1.6.5",
|
||||||
"ng-circle-progress": "^1.6.0",
|
"ng-circle-progress": "^1.6.0",
|
||||||
"ng2-file-upload": "^3.0.0",
|
"ng2-file-upload": "^1.4.0",
|
||||||
"ngx-childprocess": "^0.0.6",
|
"ngx-childprocess": "^0.0.6",
|
||||||
"ngx-device-detector": "4.0.1",
|
"ngx-device-detector": "^2.1.1",
|
||||||
"ngx-electron": "^2.2.0",
|
"ngx-electron": "^2.2.0",
|
||||||
"node-fetch": "^3.2.10",
|
"node-fetch": "^3.2.10",
|
||||||
"notosans-fontface": "^1.3.0",
|
"notosans-fontface": "1.2.2",
|
||||||
"postcss-loader": "^6.2.1",
|
|
||||||
"prettier-plugin-organize-imports": "^2.3.4",
|
"prettier-plugin-organize-imports": "^2.3.4",
|
||||||
"rxjs": "^6.6.7",
|
"rxjs": "^6.6.7",
|
||||||
"rxjs-compat": "^6.6.7",
|
"rxjs-compat": "^6.6.7",
|
||||||
"save-svg-as-png": "^1.4.17",
|
"save-svg-as-png": "^1.4.17",
|
||||||
|
"snyk": "^1.1064.0",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"svg-crowbar": "^0.7.0",
|
"svg-crowbar": "^0.7.0",
|
||||||
"tree-kill": "^1.2.2",
|
"tree-kill": "^1.2.2",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.3.1",
|
||||||
"typeface-roboto": "^1.1.13",
|
"typeface-roboto": "^1.1.13",
|
||||||
"xterm": "^4.18.0",
|
"xterm": "^4.15.0",
|
||||||
"xterm-addon-attach": "^0.6.0",
|
"xterm-addon-attach": "^0.6.0",
|
||||||
"xterm-addon-fit": "^0.5.0",
|
"xterm-addon-fit": "^0.5.0",
|
||||||
"yargs": "^17.4.1",
|
"yargs": "^17.2.1",
|
||||||
"zone.js": "^0.11.5"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^14.2.12",
|
"@angular-devkit/build-angular": "^12.2.12",
|
||||||
"@angular/cli": "^14.2.12",
|
"@angular/cli": "^12.2.12",
|
||||||
"@angular/compiler-cli": "^14.3.0",
|
"@angular/compiler-cli": "^12.2.12",
|
||||||
"@angular/language-service": "^14.3.0",
|
"@angular/language-service": "^12.2.12",
|
||||||
"@sentry/cli": "^2.0.4",
|
"@sentry/cli": "^1.71.0",
|
||||||
"@sentry/electron": "^3.0.7",
|
"@sentry/electron": "^2.5.4",
|
||||||
"@types/jasmine": "^4.0.3",
|
"@types/jasmine": "^3.10.2",
|
||||||
"@types/jasminewd2": "^2.0.10",
|
"@types/jasminewd2": "^2.0.10",
|
||||||
"@types/node": "^17.0.31",
|
"@types/node": "16.11.6",
|
||||||
"codelyzer": "^0.0.28",
|
"codelyzer": "^6.0.2",
|
||||||
"electron": "13.6.6",
|
"electron": "^13.6.6",
|
||||||
"electron-builder": "^23.0.3",
|
"electron-builder": "^22.9.1",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"jasmine-core": "^4.1.0",
|
"jasmine-core": "~3.10.1",
|
||||||
"jasmine-spec-reporter": "^7.0.0",
|
"jasmine-spec-reporter": "~7.0.0",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"karma": "^6.3.19",
|
"karma": "^6.3.16",
|
||||||
"karma-chrome-launcher": "^3.1.1",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"karma-cli": "^2.0.0",
|
"karma-cli": "^2.0.0",
|
||||||
"karma-coverage-istanbul-reporter": "^3.0.3",
|
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||||
"karma-jasmine": "^5.0.0",
|
"karma-jasmine": "~4.0.1",
|
||||||
"karma-jasmine-html-reporter": "^1.7.0",
|
"karma-jasmine-html-reporter": "^1.7.0",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"popper.js": "^1.16.1",
|
"popper.js": "^1.16.1",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^2.4.1",
|
||||||
"protractor": "^7.0.0",
|
"protractor": "^7.0.0",
|
||||||
"replace": "^1.2.1",
|
"replace": "^1.2.1",
|
||||||
"rxjs-tslint": "^0.1.8",
|
"rxjs-tslint": "^0.1.8",
|
||||||
"ts-mockito": "^2.6.1",
|
"ts-mockito": "^2.6.1",
|
||||||
"ts-node": "^10.7.0",
|
"ts-node": "~10.4.0",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.3",
|
||||||
"tslint-config-prettier": "^1.18.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
"typescript": "4.6.4",
|
"typescript": "4.2.3",
|
||||||
"webpack": "^5.72.0",
|
"webpack": "5.76.0",
|
||||||
"yarn-upgrade-all": "^0.7.1"
|
"yarn-upgrade-all": "^0.5.4"
|
||||||
},
|
},
|
||||||
"greenkeeper": {
|
"greenkeeper": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
setuptools==65.5.1
|
setuptools==71.1.0
|
||||||
cx_Freeze==5.1.1
|
cx_Freeze==5.1.1
|
||||||
requests==2.31.0
|
requests==2.32.3
|
||||||
packaging==20.9
|
packaging==20.9
|
||||||
appdirs==1.4.4
|
appdirs==1.4.4
|
||||||
psutil==5.8.0
|
psutil==5.8.0
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
||||||
|
|
||||||
Current version: 2.2.24
|
Current version: 2.2.32
|
||||||
|
|
||||||
Bug Fixes & enhancements
|
Bug Fixes & enhancements
|
||||||
- security fixes
|
- Fixed generated capture file is not valid
|
||||||
|
- Fixed Docker additional directories
|
||||||
|
|
||||||
Current version: 2020.4.0-beta.1
|
Current version: 2020.4.0-beta.1
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ GNS3 Web UI 2020.2.0-beta.4
|
|||||||
Bug Fixes
|
Bug Fixes
|
||||||
- New port setting for GNS3 VM preferences
|
- New port setting for GNS3 VM preferences
|
||||||
- Option to auto-hide menu toolbar on the left side
|
- Option to auto-hide menu toolbar on the left side
|
||||||
-Controller type in template preferences
|
- Server type in template preferences
|
||||||
- Error when selecting existing Docker image
|
- Error when selecting existing Docker image
|
||||||
- Default values in templates
|
- Default values in templates
|
||||||
- TypeError: Cannot read property 'message' of undefined
|
- TypeError: Cannot read property 'message' of undefined
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import { BundledControllerFinderComponent } from './components/bundled-controller-finder/bundled-controller-finder.component';
|
import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component';
|
||||||
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
||||||
import { HelpComponent } from './components/help/help.component';
|
import { HelpComponent } from './components/help/help.component';
|
||||||
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
||||||
import { LoginComponent } from './components/login/login.component';
|
|
||||||
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
|
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
|
||||||
import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component';
|
import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component';
|
||||||
import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component';
|
import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component';
|
||||||
@ -24,6 +23,7 @@ import { AddIosTemplateComponent } from './components/preferences/dynamips/add-i
|
|||||||
import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component';
|
import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component';
|
||||||
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
||||||
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
||||||
|
import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component';
|
||||||
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
||||||
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
||||||
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
||||||
@ -44,261 +44,157 @@ import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs
|
|||||||
import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component';
|
import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component';
|
||||||
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
||||||
import { ProjectsComponent } from './components/projects/projects.component';
|
import { ProjectsComponent } from './components/projects/projects.component';
|
||||||
import { ControllersComponent } from './components/controllers/controllers.component';
|
import { ServersComponent } from './components/servers/servers.component';
|
||||||
import { ConsoleComponent } from './components/settings/console/console.component';
|
import { ConsoleComponent } from './components/settings/console/console.component';
|
||||||
import { SettingsComponent } from './components/settings/settings.component';
|
import { SettingsComponent } from './components/settings/settings.component';
|
||||||
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
||||||
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
||||||
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
||||||
import { ConsoleGuard } from './guards/console-guard';
|
import { ConsoleGuard } from './guards/console-guard';
|
||||||
import { LoginGuard } from './guards/login-guard';
|
|
||||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||||
import { ControllerResolve } from './resolvers/controller-resolve';
|
import { ServerResolve } from './resolvers/server-resolve';
|
||||||
import { UserManagementComponent } from './components/user-management/user-management.component';
|
|
||||||
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
|
||||||
import { ImageManagerComponent } from './components/image-manager/image-manager.component';
|
|
||||||
import { UserDetailComponent } from "./components/user-management/user-detail/user-detail.component";
|
|
||||||
import { UserDetailResolver } from "./resolvers/user-detail.resolver";
|
|
||||||
import { ManagementComponent } from "./components/management/management.component";
|
|
||||||
import { UserGroupsResolver } from "./resolvers/user-groups.resolver";
|
|
||||||
import { GroupManagementComponent } from "./components/group-management/group-management.component";
|
|
||||||
import { RoleManagementComponent } from "./components/role-management/role-management.component";
|
|
||||||
import { GroupDetailsComponent } from "./components/group-details/group-details.component";
|
|
||||||
import { GroupMembersResolver } from "./resolvers/group-members.resolver";
|
|
||||||
import { GroupResolver } from "./resolvers/group.resolver";
|
|
||||||
import { GroupRoleResolver } from "./resolvers/group-role.resolver";
|
|
||||||
import { RoleDetailComponent } from "./components/role-management/role-detail/role-detail.component";
|
|
||||||
import { RoleDetailResolver } from "./resolvers/role-detail.resolver";
|
|
||||||
import { AclManagementComponent } from "@components/acl-management/acl-management.component";
|
|
||||||
import { ResourcePoolsManagementComponent } from "@components/resource-pools-management/resource-pools-management.component";
|
|
||||||
import { ResourcePoolDetailsComponent } from "@components/resource-pool-details/resource-pool-details.component";
|
|
||||||
import { ResourcePoolsResolver } from "@resolvers/resource-pools.resolver";
|
|
||||||
import { GroupAcesResolver } from "@resolvers/group-ace.resolver.ts.resolver";
|
|
||||||
import { UserAcesResolver } from "@resolvers/user-aces.resolver";
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: DefaultLayoutComponent,
|
component: DefaultLayoutComponent,
|
||||||
children: [
|
children: [
|
||||||
{ path: '', redirectTo: 'controllers', pathMatch: 'full' },
|
{ path: '', redirectTo: 'servers', pathMatch: 'full' },
|
||||||
{ path: 'controllers', component: ControllersComponent },
|
{ path: 'servers', component: ServersComponent },
|
||||||
{ path: 'bundled', component: BundledControllerFinderComponent },
|
{ path: 'bundled', component: BundledServerFinderComponent },
|
||||||
{ path: 'controller/:controller_id/login', component: LoginComponent },
|
|
||||||
{ path: 'controller/:controller_id/loggeduser', component: LoggedUserComponent },
|
|
||||||
{path : 'controller/:controller_id/image-manager', component: ImageManagerComponent},
|
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/projects',
|
path: 'server/:server_id/projects',
|
||||||
component: ProjectsComponent,
|
component: ProjectsComponent,
|
||||||
canActivate: [LoginGuard],
|
resolve: { server: ServerResolve },
|
||||||
resolve: { controller: ControllerResolve },
|
|
||||||
},
|
|
||||||
{ path: 'controller/:controller_id/help', component: HelpComponent },
|
|
||||||
{ path: 'controller/:controller_id/settings', component: SettingsComponent },
|
|
||||||
{ path: 'controller/:controller_id/settings/console', component: ConsoleComponent },
|
|
||||||
{
|
|
||||||
path: 'controller/:controller_id/management/users/:user_id',
|
|
||||||
component: UserDetailComponent,
|
|
||||||
canActivate: [LoginGuard],
|
|
||||||
resolve: {
|
|
||||||
user: UserDetailResolver,
|
|
||||||
groups: UserGroupsResolver,
|
|
||||||
aces: UserAcesResolver,
|
|
||||||
controller: ControllerResolve},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'controller/:controller_id/management/resourcePools/:pool_id',
|
|
||||||
component: ResourcePoolDetailsComponent,
|
|
||||||
canActivate: [LoginGuard],
|
|
||||||
resolve: {
|
|
||||||
pool: ResourcePoolsResolver,
|
|
||||||
controller: ControllerResolve
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
{ path: 'help', component: HelpComponent },
|
||||||
|
{ path: 'settings', component: SettingsComponent },
|
||||||
|
{ path: 'settings/console', component: ConsoleComponent },
|
||||||
{ path: 'installed-software', component: InstalledSoftwareComponent },
|
{ path: 'installed-software', component: InstalledSoftwareComponent },
|
||||||
{ path: 'controller/:controller_id/systemstatus', component: SystemStatusComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/systemstatus', component: SystemStatusComponent },
|
||||||
|
|
||||||
{ path: 'controller/:controller_ip/:controller_port/project/:project_id', component: DirectLinkComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_ip/:server_port/project/:project_id', component: DirectLinkComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/project/:project_id/snapshots',
|
path: 'server/:server_id/project/:project_id/snapshots',
|
||||||
component: ListOfSnapshotsComponent,
|
component: ListOfSnapshotsComponent,
|
||||||
canActivate: [LoginGuard],
|
resolve: { server: ServerResolve },
|
||||||
resolve: { controller: ControllerResolve },
|
|
||||||
},
|
},
|
||||||
{ path: 'controller/:controller_id/preferences', component: PreferencesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences', component: PreferencesComponent },
|
||||||
// { path: 'controller/:controller_id/preferences/general', component: GeneralPreferencesComponent },
|
{ path: 'server/:server_id/preferences/gns3vm', component: Gns3vmComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/builtin', component: BuiltInPreferencesComponent, canActivate: [LoginGuard] },
|
// { path: 'server/:server_id/preferences/general', component: GeneralPreferencesComponent },
|
||||||
|
{ path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent },
|
||||||
|
|
||||||
{ path: 'controller/:controller_id/preferences/builtin/ethernet-hubs', component: EthernetHubsTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs', component: EthernetHubsTemplatesComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/ethernet-hubs/addtemplate',
|
path: 'server/:server_id/preferences/builtin/ethernet-hubs/addtemplate',
|
||||||
component: EthernetHubsAddTemplateComponent,
|
component: EthernetHubsAddTemplateComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/ethernet-hubs/:template_id',
|
path: 'server/:server_id/preferences/builtin/ethernet-hubs/:template_id',
|
||||||
component: EthernetHubsTemplateDetailsComponent,
|
component: EthernetHubsTemplateDetailsComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/ethernet-switches',
|
path: 'server/:server_id/preferences/builtin/ethernet-switches',
|
||||||
component: EthernetSwitchesTemplatesComponent,
|
component: EthernetSwitchesTemplatesComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/ethernet-switches/addtemplate',
|
path: 'server/:server_id/preferences/builtin/ethernet-switches/addtemplate',
|
||||||
component: EthernetSwitchesAddTemplateComponent,
|
component: EthernetSwitchesAddTemplateComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/ethernet-switches/:template_id',
|
path: 'server/:server_id/preferences/builtin/ethernet-switches/:template_id',
|
||||||
component: EthernetSwitchesTemplateDetailsComponent,
|
component: EthernetSwitchesTemplateDetailsComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{ path: 'controller/:controller_id/preferences/builtin/cloud-nodes', component: CloudNodesTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/builtin/cloud-nodes', component: CloudNodesTemplatesComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/cloud-nodes/addtemplate',
|
path: 'server/:server_id/preferences/builtin/cloud-nodes/addtemplate',
|
||||||
component: CloudNodesAddTemplateComponent,
|
component: CloudNodesAddTemplateComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/builtin/cloud-nodes/:template_id',
|
path: 'server/:server_id/preferences/builtin/cloud-nodes/:template_id',
|
||||||
component: CloudNodesTemplateDetailsComponent,
|
component: CloudNodesTemplateDetailsComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//{ path: 'controller/:controller_id/preferences/dynamips', component: DynamipsPreferencesComponent },
|
//{ path: 'server/:server_id/preferences/dynamips', component: DynamipsPreferencesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/dynamips/templates', component: IosTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/dynamips/templates', component: IosTemplatesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/dynamips/templates/addtemplate', component: AddIosTemplateComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/dynamips/templates/addtemplate', component: AddIosTemplateComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/dynamips/templates/:template_id', component: IosTemplateDetailsComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/dynamips/templates/:template_id', component: IosTemplateDetailsComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/dynamips/templates/:template_id/copy',
|
path: 'server/:server_id/preferences/dynamips/templates/:template_id/copy',
|
||||||
component: CopyIosTemplateComponent,
|
component: CopyIosTemplateComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// { path: 'controller/:controller_id/preferences/qemu', component: QemuPreferencesComponent },
|
// { path: 'server/:server_id/preferences/qemu', component: QemuPreferencesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/qemu/templates', component: QemuVmTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/qemu/templates', component: QemuVmTemplatesComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/qemu/templates/:template_id/copy',
|
path: 'server/:server_id/preferences/qemu/templates/:template_id/copy',
|
||||||
component: CopyQemuVmTemplateComponent,
|
component: CopyQemuVmTemplateComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{ path: 'controller/:controller_id/preferences/qemu/templates/:template_id', component: QemuVmTemplateDetailsComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/qemu/templates/:template_id', component: QemuVmTemplateDetailsComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/qemu/addtemplate', component: AddQemuVmTemplateComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/qemu/addtemplate', component: AddQemuVmTemplateComponent },
|
||||||
|
|
||||||
// { path: 'controller/:controller_id/preferences/vpcs', component: VpcsPreferencesComponent },
|
// { path: 'server/:server_id/preferences/vpcs', component: VpcsPreferencesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/vpcs/templates', component: VpcsTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/vpcs/templates', component: VpcsTemplatesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/vpcs/addtemplate', component: AddVpcsTemplateComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/vpcs/addtemplate', component: AddVpcsTemplateComponent },
|
||||||
|
|
||||||
// { path: 'controller/:controller_id/preferences/virtualbox', component: VirtualBoxPreferencesComponent },
|
// { path: 'server/:server_id/preferences/virtualbox', component: VirtualBoxPreferencesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/virtualbox/templates', component: VirtualBoxTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/virtualbox/templates', component: VirtualBoxTemplatesComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/virtualbox/templates/:template_id',
|
path: 'server/:server_id/preferences/virtualbox/templates/:template_id',
|
||||||
component: VirtualBoxTemplateDetailsComponent,
|
component: VirtualBoxTemplateDetailsComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{ path: 'controller/:controller_id/preferences/virtualbox/addtemplate', component: AddVirtualBoxTemplateComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/virtualbox/addtemplate', component: AddVirtualBoxTemplateComponent },
|
||||||
|
|
||||||
// { path: 'controller/:controller_id/preferences/vmware', component: VmwarePreferencesComponent },
|
// { path: 'server/:server_id/preferences/vmware', component: VmwarePreferencesComponent },
|
||||||
{ path: 'controller/:controller_id/preferences/vmware/templates', component: VmwareTemplatesComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/vmware/templates', component: VmwareTemplatesComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/vmware/templates/:template_id',
|
path: 'server/:server_id/preferences/vmware/templates/:template_id',
|
||||||
component: VmwareTemplateDetailsComponent,
|
component: VmwareTemplateDetailsComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{ path: 'controller/:controller_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent, canActivate: [LoginGuard] },
|
{ path: 'server/:server_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent },
|
||||||
|
|
||||||
{ path: 'controller/:controller_id/preferences/docker/templates', component: DockerTemplatesComponent, canActivate: [LoginGuard] },
|
// { path: 'server/:server_id/preferences/traceng', component: TracengPreferencesComponent },
|
||||||
|
// { path: 'server/:server_id/preferences/traceng/templates', component: TracengTemplatesComponent },
|
||||||
|
// { path: 'server/:server_id/preferences/traceng/templates/:template_id', component: TracengTemplateDetailsComponent },
|
||||||
|
// { path: 'server/:server_id/preferences/traceng/addtemplate', component: AddTracengTemplateComponent },
|
||||||
|
|
||||||
|
{ path: 'server/:server_id/preferences/docker/templates', component: DockerTemplatesComponent },
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/docker/templates/:template_id',
|
path: 'server/:server_id/preferences/docker/templates/:template_id',
|
||||||
component: DockerTemplateDetailsComponent,
|
component: DockerTemplateDetailsComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/preferences/docker/templates/:template_id/copy',
|
path: 'server/:server_id/preferences/docker/templates/:template_id/copy',
|
||||||
component: CopyDockerTemplateComponent,
|
component: CopyDockerTemplateComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
|
||||||
{ path: 'controller/:controller_id/preferences/docker/addtemplate', component: AddDockerTemplateComponent, canActivate: [LoginGuard] },
|
|
||||||
{ path: 'controller/:controller_id/preferences/iou/templates', component: IouTemplatesComponent, canActivate: [LoginGuard] },
|
|
||||||
{ path: 'controller/:controller_id/preferences/iou/templates/:template_id', component: IouTemplateDetailsComponent, canActivate: [LoginGuard] },
|
|
||||||
{
|
|
||||||
path: 'controller/:controller_id/preferences/iou/templates/:template_id/copy',
|
|
||||||
component: CopyIouTemplateComponent,
|
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
|
||||||
{ path: 'controller/:controller_id/preferences/iou/addtemplate', component: AddIouTemplateComponent, canActivate: [LoginGuard] },
|
|
||||||
{
|
|
||||||
path: 'controller/:controller_id/management',
|
|
||||||
component: ManagementComponent,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'users',
|
|
||||||
component: UserManagementComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'groups',
|
|
||||||
component: GroupManagementComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'roles',
|
|
||||||
component: RoleManagementComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "pools",
|
|
||||||
component: ResourcePoolsManagementComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'ACL',
|
|
||||||
component: AclManagementComponent
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'controller/:controller_id/management/groups/:user_group_id',
|
|
||||||
component: GroupDetailsComponent,
|
|
||||||
resolve: {
|
|
||||||
members: GroupMembersResolver,
|
|
||||||
controller: ControllerResolve,
|
|
||||||
group: GroupResolver,
|
|
||||||
aces: GroupAcesResolver
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'controller/:controller_id/management/roles/:role_id',
|
|
||||||
component: RoleDetailComponent,
|
|
||||||
resolve: {
|
|
||||||
role: RoleDetailResolver,
|
|
||||||
controller: ControllerResolve
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
{ path: 'server/:server_id/preferences/docker/addtemplate', component: AddDockerTemplateComponent },
|
||||||
|
|
||||||
|
{ path: 'server/:server_id/preferences/iou/templates', component: IouTemplatesComponent },
|
||||||
|
{ path: 'server/:server_id/preferences/iou/templates/:template_id', component: IouTemplateDetailsComponent },
|
||||||
|
{ path: 'server/:server_id/preferences/iou/templates/:template_id/copy', component: CopyIouTemplateComponent },
|
||||||
|
{ path: 'server/:server_id/preferences/iou/addtemplate', component: AddIouTemplateComponent },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/project/:project_id',
|
path: 'server/:server_id/project/:project_id',
|
||||||
component: ProjectMapComponent,
|
component: ProjectMapComponent,
|
||||||
canActivate: [LoginGuard],
|
|
||||||
canDeactivate: [ConsoleGuard],
|
canDeactivate: [ConsoleGuard],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'controller/:controller_id/project/:project_id/nodes/:node_id',
|
path: 'server/:server_id/project/:project_id/nodes/:node_id',
|
||||||
component: WebConsoleFullWindowComponent,
|
component: WebConsoleFullWindowComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'static/web-ui/controller/:controller_id/project/:project_id/nodes/:node_id',
|
path: 'static/web-ui/server/:server_id/project/:project_id/nodes/:node_id',
|
||||||
component: WebConsoleFullWindowComponent,
|
component: WebConsoleFullWindowComponent,
|
||||||
canActivate: [LoginGuard]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
component: PageNotFoundComponent,
|
component: PageNotFoundComponent,
|
||||||
}
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -311,5 +207,4 @@ const routes: Routes = [
|
|||||||
],
|
],
|
||||||
exports: [RouterModule],
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class AppRoutingModule {
|
export class AppRoutingModule {}
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div [ngClass]="{ dark: darkThemeEnabled, light: !darkThemeEnabled }">
|
<div [ngClass]="{ dark: darkThemeEnabled, light: !darkThemeEnabled }">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
<app-adbutler></app-adbutler>
|
<!-- <app-adbutler></app-adbutler> -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { ElectronService, NgxElectronModule } from 'ngx-electron';
|
import { ElectronService, NgxElectronModule } from 'ngx-electron';
|
||||||
@ -16,8 +16,8 @@ describe('AppComponent', () => {
|
|||||||
let electronService: ElectronService;
|
let electronService: ElectronService;
|
||||||
let settingsService: SettingsService;
|
let settingsService: SettingsService;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
|
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
|
||||||
providers: [SettingsService, ProgressService],
|
providers: [SettingsService, ProgressService],
|
||||||
@ -26,7 +26,7 @@ describe('AppComponent', () => {
|
|||||||
|
|
||||||
electronService = TestBed.inject(ElectronService);
|
electronService = TestBed.inject(ElectronService);
|
||||||
settingsService = TestBed.inject(SettingsService);
|
settingsService = TestBed.inject(SettingsService);
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(AppComponent);
|
fixture = TestBed.createComponent(AppComponent);
|
||||||
@ -34,29 +34,29 @@ describe('AppComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create the app', async() => {
|
it('should create the app', async(() => {
|
||||||
const app = fixture.debugElement.componentInstance;
|
const app = fixture.debugElement.componentInstance;
|
||||||
await expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
});
|
}));
|
||||||
|
|
||||||
it('should have footer', async() => {
|
it('should have footer', async(() => {
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
await expect(compiled.querySelector('router-outlet').textContent).toEqual('');
|
expect(compiled.querySelector('router-outlet').textContent).toEqual('');
|
||||||
});
|
}));
|
||||||
|
|
||||||
it('should receive changed settings and forward to electron', async() => {
|
it('should receive changed settings and forward to electron', async(() => {
|
||||||
await spyOnProperty(electronService, 'isElectronApp').and.returnValue(true);
|
spyOnProperty(electronService, 'isElectronApp').and.returnValue(true);
|
||||||
settingsService.setReportsSettings(true);
|
settingsService.setReportsSettings(true);
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
settingsService.setReportsSettings(false);
|
settingsService.setReportsSettings(false);
|
||||||
});
|
}));
|
||||||
|
|
||||||
it('should receive changed settings and do not forward to electron', async() => {
|
it('should receive changed settings and do not forward to electron', async(() => {
|
||||||
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
||||||
spyOnProperty(electronService, 'isElectronApp').and.returnValue(false);
|
spyOnProperty(electronService, 'isElectronApp').and.returnValue(false);
|
||||||
settingsService.setReportsSettings(true);
|
settingsService.setReportsSettings(true);
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
settingsService.setReportsSettings(false);
|
settingsService.setReportsSettings(false);
|
||||||
await expect(spy.send).not.toHaveBeenCalled();
|
expect(spy.send).not.toHaveBeenCalled();
|
||||||
});
|
}));
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
/* tslint:disable */
|
|
||||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
import { OverlayModule } from '@angular/cdk/overlay';
|
import { OverlayModule } from '@angular/cdk/overlay';
|
||||||
import { CdkTableModule } from '@angular/cdk/table';
|
import { CdkTableModule } from '@angular/cdk/table';
|
||||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { ErrorHandler, NgModule } from '@angular/core';
|
import { ErrorHandler, NgModule } from '@angular/core';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||||
@ -30,7 +29,7 @@ import { ProgressDialogService } from './common/progress-dialog/progress-dialog.
|
|||||||
import { ProgressComponent } from './common/progress/progress.component';
|
import { ProgressComponent } from './common/progress/progress.component';
|
||||||
import { ProgressService } from './common/progress/progress.service';
|
import { ProgressService } from './common/progress/progress.service';
|
||||||
import { AdbutlerComponent } from './components/adbutler/adbutler.component';
|
import { AdbutlerComponent } from './components/adbutler/adbutler.component';
|
||||||
import { BundledControllerFinderComponent } from './components/bundled-controller-finder/bundled-controller-finder.component';
|
import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component';
|
||||||
import { InformationDialogComponent } from './components/dialogs/information-dialog.component';
|
import { InformationDialogComponent } from './components/dialogs/information-dialog.component';
|
||||||
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
||||||
import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component';
|
import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component';
|
||||||
@ -75,6 +74,7 @@ import { DynamipsPreferencesComponent } from './components/preferences/dynamips/
|
|||||||
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
||||||
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
||||||
import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component';
|
import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component';
|
||||||
|
import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component';
|
||||||
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
||||||
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
||||||
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
||||||
@ -85,6 +85,10 @@ import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-
|
|||||||
import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component';
|
import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component';
|
||||||
import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component';
|
import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component';
|
||||||
import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component';
|
import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component';
|
||||||
|
import { AddTracengTemplateComponent } from './components/preferences/traceng/add-traceng/add-traceng-template.component';
|
||||||
|
import { TracengPreferencesComponent } from './components/preferences/traceng/traceng-preferences/traceng-preferences.component';
|
||||||
|
import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component';
|
||||||
|
import { TracengTemplatesComponent } from './components/preferences/traceng/traceng-templates/traceng-templates.component';
|
||||||
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
||||||
import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component';
|
import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component';
|
||||||
import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component';
|
import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component';
|
||||||
@ -113,7 +117,6 @@ import { DeleteActionComponent } from './components/project-map/context-menu/act
|
|||||||
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
||||||
import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component';
|
import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component';
|
||||||
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
||||||
import { EditLinkStyleActionComponent } from './components/project-map/context-menu/actions/edit-link-style-action/edit-link-style-action.component';
|
|
||||||
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
||||||
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
|
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
|
||||||
import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component';
|
import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component';
|
||||||
@ -131,16 +134,13 @@ import { StartCaptureOnStartedLinkActionComponent } from './components/project-m
|
|||||||
import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component';
|
import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component';
|
||||||
import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component';
|
import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component';
|
||||||
import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component';
|
import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component';
|
||||||
import { IsolateNodeActionComponent } from './components/project-map/context-menu/actions/isolate-node-action/isolate-node-action.component';
|
import { StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
|
||||||
import { UnisolateNodeActionComponent } from './components/project-map/context-menu/actions/unisolate-node-action/unisolate-node-action.component';
|
|
||||||
import {StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
|
|
||||||
import { SuspendLinkActionComponent } from './components/project-map/context-menu/actions/suspend-link/suspend-link-action.component';
|
import { SuspendLinkActionComponent } from './components/project-map/context-menu/actions/suspend-link/suspend-link-action.component';
|
||||||
import { SuspendNodeActionComponent } from './components/project-map/context-menu/actions/suspend-node-action/suspend-node-action.component';
|
import { SuspendNodeActionComponent } from './components/project-map/context-menu/actions/suspend-node-action/suspend-node-action.component';
|
||||||
import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component';
|
import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component';
|
||||||
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
|
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
|
||||||
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
|
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
|
||||||
import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component';
|
import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component';
|
||||||
import { LinkStyleEditorDialogComponent } from './components/project-map/drawings-editors/link-style-editor/link-style-editor.component';
|
|
||||||
import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component';
|
import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component';
|
||||||
import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component';
|
import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component';
|
||||||
import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer';
|
import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer';
|
||||||
@ -165,6 +165,7 @@ import { ConfiguratorDialogNatComponent } from './components/project-map/node-ed
|
|||||||
import { ConfiguratorDialogQemuComponent } from './components/project-map/node-editors/configurator/qemu/configurator-qemu.component';
|
import { ConfiguratorDialogQemuComponent } from './components/project-map/node-editors/configurator/qemu/configurator-qemu.component';
|
||||||
import { QemuImageCreatorComponent } from './components/project-map/node-editors/configurator/qemu/qemu-image-creator/qemu-image-creator.component';
|
import { QemuImageCreatorComponent } from './components/project-map/node-editors/configurator/qemu/qemu-image-creator/qemu-image-creator.component';
|
||||||
import { ConfiguratorDialogSwitchComponent } from './components/project-map/node-editors/configurator/switch/configurator-switch.component';
|
import { ConfiguratorDialogSwitchComponent } from './components/project-map/node-editors/configurator/switch/configurator-switch.component';
|
||||||
|
import { ConfiguratorDialogTracengComponent } from './components/project-map/node-editors/configurator/traceng/configurator-traceng.component';
|
||||||
import { ConfiguratorDialogVirtualBoxComponent } from './components/project-map/node-editors/configurator/virtualbox/configurator-virtualbox.component';
|
import { ConfiguratorDialogVirtualBoxComponent } from './components/project-map/node-editors/configurator/virtualbox/configurator-virtualbox.component';
|
||||||
import { ConfiguratorDialogVmwareComponent } from './components/project-map/node-editors/configurator/vmware/configurator-vmware.component';
|
import { ConfiguratorDialogVmwareComponent } from './components/project-map/node-editors/configurator/vmware/configurator-vmware.component';
|
||||||
import { ConfiguratorDialogVpcsComponent } from './components/project-map/node-editors/configurator/vpcs/configurator-vpcs.component';
|
import { ConfiguratorDialogVpcsComponent } from './components/project-map/node-editors/configurator/vpcs/configurator-vpcs.component';
|
||||||
@ -174,7 +175,6 @@ import { PacketFiltersDialogComponent } from './components/project-map/packet-ca
|
|||||||
import { StartCaptureDialogComponent } from './components/project-map/packet-capturing/start-capture/start-capture.component';
|
import { StartCaptureDialogComponent } from './components/project-map/packet-capturing/start-capture/start-capture.component';
|
||||||
import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component';
|
import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component';
|
||||||
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
||||||
import { ProjectReadmeComponent } from './components/project-map/project-readme/project-readme.component';
|
|
||||||
import { ScreenshotDialogComponent } from './components/project-map/screenshot-dialog/screenshot-dialog.component';
|
import { ScreenshotDialogComponent } from './components/project-map/screenshot-dialog/screenshot-dialog.component';
|
||||||
import { WebConsoleComponent } from './components/project-map/web-console/web-console.component';
|
import { WebConsoleComponent } from './components/project-map/web-console/web-console.component';
|
||||||
import { AddBlankProjectDialogComponent } from './components/projects/add-blank-project-dialog/add-blank-project-dialog.component';
|
import { AddBlankProjectDialogComponent } from './components/projects/add-blank-project-dialog/add-blank-project-dialog.component';
|
||||||
@ -182,15 +182,15 @@ import { ChooseNameDialogComponent } from './components/projects/choose-name-dia
|
|||||||
import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component';
|
import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component';
|
||||||
import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-dialog.component';
|
||||||
import { EditProjectDialogComponent } from './components/projects/edit-project-dialog/edit-project-dialog.component';
|
import { EditProjectDialogComponent } from './components/projects/edit-project-dialog/edit-project-dialog.component';
|
||||||
import { ReadmeEditorComponent } from './components/projects/edit-project-dialog/readme-editor/readme-editor.component';
|
|
||||||
import { ImportProjectDialogComponent } from './components/projects/import-project-dialog/import-project-dialog.component';
|
import { ImportProjectDialogComponent } from './components/projects/import-project-dialog/import-project-dialog.component';
|
||||||
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
||||||
import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component';
|
import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component';
|
||||||
import { ProjectsComponent } from './components/projects/projects.component';
|
import { ProjectsComponent } from './components/projects/projects.component';
|
||||||
import { SaveProjectDialogComponent } from './components/projects/save-project-dialog/save-project-dialog.component';
|
import { SaveProjectDialogComponent } from './components/projects/save-project-dialog/save-project-dialog.component';
|
||||||
import { AddControllerDialogComponent } from './components/controllers/add-controller-dialog/add-controller-dialog.component';
|
import { AddServerDialogComponent } from './components/servers/add-server-dialog/add-server-dialog.component';
|
||||||
import { ControllerDiscoveryComponent } from './components/controllers/controller-discovery/controller-discovery.component';
|
import { ConfigureGns3VMDialogComponent } from './components/servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component';
|
||||||
import { ControllersComponent } from './components/controllers/controllers.component';
|
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
||||||
|
import { ServersComponent } from './components/servers/servers.component';
|
||||||
import { ConsoleComponent } from './components/settings/console/console.component';
|
import { ConsoleComponent } from './components/settings/console/console.component';
|
||||||
import { SettingsComponent } from './components/settings/settings.component';
|
import { SettingsComponent } from './components/settings/settings.component';
|
||||||
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
||||||
@ -204,19 +204,18 @@ import { TemplateComponent } from './components/template/template.component';
|
|||||||
import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component';
|
import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component';
|
||||||
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
||||||
import { DataSourceFilter } from './filters/dataSourceFilter';
|
import { DataSourceFilter } from './filters/dataSourceFilter';
|
||||||
import { AuthImageFilter } from './filters/authImageFilter';
|
|
||||||
import { DateFilter } from './filters/dateFilter.pipe';
|
import { DateFilter } from './filters/dateFilter.pipe';
|
||||||
import { NameFilter } from './filters/nameFilter.pipe';
|
import { NameFilter } from './filters/nameFilter.pipe';
|
||||||
import { ProjectsFilter } from './filters/projectsFilter.pipe';
|
import { ProjectsFilter } from './filters/projectsFilter.pipe';
|
||||||
import { SearchFilter } from './filters/searchFilter.pipe';
|
import { SearchFilter } from './filters/searchFilter.pipe';
|
||||||
import { TemplateFilter } from './filters/templateFilter.pipe';
|
import { TemplateFilter } from './filters/templateFilter.pipe';
|
||||||
import { ConsoleGuard } from './guards/console-guard';
|
import { ConsoleGuard } from './guards/console-guard';
|
||||||
import { LoginGuard } from './guards/login-guard';
|
|
||||||
import { ProjectWebServiceHandler } from './handlers/project-web-service-handler';
|
import { ProjectWebServiceHandler } from './handlers/project-web-service-handler';
|
||||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||||
import { MATERIAL_IMPORTS } from './material.imports';
|
import { MATERIAL_IMPORTS } from './material.imports';
|
||||||
import { ControllerResolve } from './resolvers/controller-resolve';
|
import { ServerResolve } from './resolvers/server-resolve';
|
||||||
import { ApplianceService } from './services/appliances.service';
|
import { ApplianceService } from './services/appliances.service';
|
||||||
|
import { ProtocolHandlerService } from './services/protocol-handler.service';
|
||||||
import { BuiltInTemplatesConfigurationService } from './services/built-in-templates-configuration.service';
|
import { BuiltInTemplatesConfigurationService } from './services/built-in-templates-configuration.service';
|
||||||
import { BuiltInTemplatesService } from './services/built-in-templates.service';
|
import { BuiltInTemplatesService } from './services/built-in-templates.service';
|
||||||
import { ComputeService } from './services/compute.service';
|
import { ComputeService } from './services/compute.service';
|
||||||
@ -224,8 +223,9 @@ import { DockerConfigurationService } from './services/docker-configuration.serv
|
|||||||
import { DockerService } from './services/docker.service';
|
import { DockerService } from './services/docker.service';
|
||||||
import { DrawingService } from './services/drawing.service';
|
import { DrawingService } from './services/drawing.service';
|
||||||
import { ExternalSoftwareDefinitionService } from './services/external-software-definition.service';
|
import { ExternalSoftwareDefinitionService } from './services/external-software-definition.service';
|
||||||
|
import { Gns3vmService } from './services/gns3vm.service';
|
||||||
import { GoogleAnalyticsService } from './services/google-analytics.service';
|
import { GoogleAnalyticsService } from './services/google-analytics.service';
|
||||||
import { HttpController, ControllerErrorHandler } from './services/http-controller.service';
|
import { HttpServer, ServerErrorHandler } from './services/http-server.service';
|
||||||
import { InfoService } from './services/info.service';
|
import { InfoService } from './services/info.service';
|
||||||
import { InstalledSoftwareService } from './services/installed-software.service';
|
import { InstalledSoftwareService } from './services/installed-software.service';
|
||||||
import { IosConfigurationService } from './services/ios-configuration.service';
|
import { IosConfigurationService } from './services/ios-configuration.service';
|
||||||
@ -244,10 +244,10 @@ import { ProjectService } from './services/project.service';
|
|||||||
import { QemuConfigurationService } from './services/qemu-configuration.service';
|
import { QemuConfigurationService } from './services/qemu-configuration.service';
|
||||||
import { QemuService } from './services/qemu.service';
|
import { QemuService } from './services/qemu.service';
|
||||||
import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service';
|
import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service';
|
||||||
import { ControllerManagementService } from './services/controller-management.service';
|
import { ServerManagementService } from './services/server-management.service';
|
||||||
import { ControllerSettingsService } from './services/controller-settings.service';
|
import { ServerSettingsService } from './services/server-settings.service';
|
||||||
import { ControllerDatabase } from './services/controller.database';
|
import { ServerDatabase } from './services/server.database';
|
||||||
import { ControllerService } from './services/controller.service';
|
import { ServerService } from './services/server.service';
|
||||||
import { SettingsService } from './services/settings.service';
|
import { SettingsService } from './services/settings.service';
|
||||||
import { ConsoleService } from './services/settings/console.service';
|
import { ConsoleService } from './services/settings/console.service';
|
||||||
import { DefaultConsoleService } from './services/settings/default-console.service';
|
import { DefaultConsoleService } from './services/settings/default-console.service';
|
||||||
@ -258,6 +258,7 @@ import { TemplateService } from './services/template.service';
|
|||||||
import { ThemeService } from './services/theme.service';
|
import { ThemeService } from './services/theme.service';
|
||||||
import { ToasterService } from './services/toaster.service';
|
import { ToasterService } from './services/toaster.service';
|
||||||
import { ToolsService } from './services/tools.service';
|
import { ToolsService } from './services/tools.service';
|
||||||
|
import { TracengService } from './services/traceng.service';
|
||||||
import { UpdatesService } from './services/updates.service';
|
import { UpdatesService } from './services/updates.service';
|
||||||
import { VersionService } from './services/version.service';
|
import { VersionService } from './services/version.service';
|
||||||
import { VirtualBoxConfigurationService } from './services/virtual-box-configuration.service';
|
import { VirtualBoxConfigurationService } from './services/virtual-box-configuration.service';
|
||||||
@ -268,403 +269,337 @@ import { VpcsConfigurationService } from './services/vpcs-configuration.service'
|
|||||||
import { VpcsService } from './services/vpcs.service';
|
import { VpcsService } from './services/vpcs.service';
|
||||||
import { NonNegativeValidator } from './validators/non-negative-validator';
|
import { NonNegativeValidator } from './validators/non-negative-validator';
|
||||||
import { RotationValidator } from './validators/rotation-validator';
|
import { RotationValidator } from './validators/rotation-validator';
|
||||||
import { MarkedDirective } from './directives/marked.directive';
|
|
||||||
import { LoginComponent } from './components/login/login.component';
|
|
||||||
import { LoginService } from './services/login.service';
|
|
||||||
import { HttpRequestsInterceptor } from './interceptors/http.interceptor';
|
|
||||||
import { UserManagementComponent } from './components/user-management/user-management.component';
|
|
||||||
import { UserService } from './services/user.service';
|
|
||||||
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
|
||||||
import { AddUserDialogComponent } from './components/user-management/add-user-dialog/add-user-dialog.component';
|
|
||||||
import { UserFilterPipe } from './filters/user-filter.pipe';
|
|
||||||
import { GroupManagementComponent } from './components/group-management/group-management.component';
|
|
||||||
import { GroupFilterPipe } from './filters/group-filter.pipe';
|
|
||||||
import { AddGroupDialogComponent } from './components/group-management/add-group-dialog/add-group-dialog.component';
|
|
||||||
import { DeleteGroupDialogComponent } from './components/group-management/delete-group-dialog/delete-group-dialog.component';
|
|
||||||
import { DeleteUserDialogComponent } from './components/user-management/delete-user-dialog/delete-user-dialog.component';
|
|
||||||
import { GroupDetailsComponent } from './components/group-details/group-details.component';
|
|
||||||
import { UserDetailComponent } from './components/user-management/user-detail/user-detail.component';
|
|
||||||
import { AddUserToGroupDialogComponent } from './components/group-details/add-user-to-group-dialog/add-user-to-group-dialog.component';
|
|
||||||
import { RemoveToGroupDialogComponent } from '@components/group-details/remove-to-group-dialog/remove-to-group-dialog.component';
|
|
||||||
import { PaginatorPipe } from './components/group-details/paginator.pipe';
|
|
||||||
import { MembersFilterPipe } from './components/group-details/members-filter.pipe';
|
|
||||||
import { ManagementComponent } from './components/management/management.component';
|
|
||||||
import {MatCheckboxModule} from "@angular/material/checkbox";
|
|
||||||
import { RoleManagementComponent } from './components/role-management/role-management.component';
|
|
||||||
import { RoleFilterPipe } from './components/role-management/role-filter.pipe';
|
|
||||||
import { AddRoleDialogComponent } from './components/role-management/add-role-dialog/add-role-dialog.component';
|
|
||||||
import { DeleteRoleDialogComponent } from './components/role-management/delete-role-dialog/delete-role-dialog.component';
|
|
||||||
import { RoleDetailComponent } from './components/role-management/role-detail/role-detail.component';
|
|
||||||
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
|
|
||||||
import {MatAutocompleteModule} from "@angular/material/autocomplete";;
|
|
||||||
import { AddRoleToGroupComponent } from './components/group-details/add-role-to-group/add-role-to-group.component';
|
|
||||||
import {MatFormFieldModule} from "@angular/material/form-field";
|
|
||||||
import { ChangeUserPasswordComponent } from './components/user-management/user-detail/change-user-password/change-user-password.component';
|
|
||||||
import {MatMenuModule} from "@angular/material/menu";
|
|
||||||
import { ImageManagerComponent } from './components/image-manager/image-manager.component';
|
|
||||||
import { AddImageDialogComponent } from './components/image-manager/add-image-dialog/add-image-dialog.component';
|
|
||||||
import { DeleteAllImageFilesDialogComponent } from './components/image-manager/deleteallfiles-dialog/deleteallfiles-dialog.component';
|
|
||||||
import { UploadingProcessbarComponent } from './common/uploading-processbar/uploading-processbar.component';
|
|
||||||
import { ExportPortableProjectComponent } from './components/export-portable-project/export-portable-project.component';
|
|
||||||
import { NodesMenuConfirmationDialogComponent } from './components/project-map/nodes-menu/nodes-menu-confirmation-dialog/nodes-menu-confirmation-dialog.component';
|
|
||||||
import { ConfirmationDeleteAllProjectsComponent } from './components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component';
|
|
||||||
import { ProjectMapLockConfirmationDialogComponent } from './components/project-map/project-map-menu/project-map-lock-confirmation-dialog/project-map-lock-confirmation-dialog.component';
|
|
||||||
import { AclManagementComponent } from "@components/acl-management/acl-management.component";
|
|
||||||
import { AddAceDialogComponent } from './components/acl-management/add-ace-dialog/add-ace-dialog.component';
|
|
||||||
import { AutocompleteComponent } from './components/acl-management/add-ace-dialog/autocomplete/autocomplete.component';
|
|
||||||
import { DeleteAceDialogComponent } from './components/acl-management/delete-ace-dialog/delete-ace-dialog.component';
|
|
||||||
import { AceFilterPipe } from './filters/ace-filter.pipe';
|
|
||||||
import { CdkAccordionModule } from "@angular/cdk/accordion";
|
|
||||||
import { CdkTreeModule } from "@angular/cdk/tree";
|
|
||||||
|
|
||||||
import { PrivilegeComponent } from './components/role-management/role-detail/privilege/privilege.component';
|
|
||||||
import { GroupPrivilegesPipe } from './components/role-management/role-detail/privilege/group-privileges.pipe';
|
|
||||||
import { ResourcePoolsManagementComponent } from './components/resource-pools-management/resource-pools-management.component';
|
|
||||||
import { AddResourcePoolDialogComponent } from './components/resource-pools-management/add-resource-pool-dialog/add-resource-pool-dialog.component';
|
|
||||||
import { DeleteResourcePoolComponent } from './components/resource-pools-management/delete-resource-pool/delete-resource-pool.component';
|
|
||||||
import { ResourcePoolsFilterPipe } from './components/resource-pools-management/resource-pools-filter.pipe';
|
|
||||||
import { ResourcePoolDetailsComponent } from './components/resource-pool-details/resource-pool-details.component';
|
|
||||||
import { DeleteResourceConfirmationDialogComponent } from './components/resource-pool-details/delete-resource-confirmation-dialog/delete-resource-confirmation-dialog.component';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
LoggedUserComponent,
|
ProjectMapComponent,
|
||||||
ProjectMapComponent,
|
ServersComponent,
|
||||||
LoginComponent,
|
AddServerDialogComponent,
|
||||||
ControllersComponent,
|
CreateSnapshotDialogComponent,
|
||||||
AddControllerDialogComponent,
|
SnapshotMenuItemComponent,
|
||||||
CreateSnapshotDialogComponent,
|
ProjectsComponent,
|
||||||
SnapshotMenuItemComponent,
|
AddBlankProjectDialogComponent,
|
||||||
ProjectsComponent,
|
ImportProjectDialogComponent,
|
||||||
AddBlankProjectDialogComponent,
|
ConfirmationDialogComponent,
|
||||||
ImportProjectDialogComponent,
|
DefaultLayoutComponent,
|
||||||
ConfirmationDialogComponent,
|
ProgressDialogComponent,
|
||||||
DefaultLayoutComponent,
|
ContextMenuComponent,
|
||||||
ProgressDialogComponent,
|
ContextConsoleMenuComponent,
|
||||||
ContextMenuComponent,
|
StartNodeActionComponent,
|
||||||
ContextConsoleMenuComponent,
|
StopNodeActionComponent,
|
||||||
StartNodeActionComponent,
|
TemplateComponent,
|
||||||
IsolateNodeActionComponent,
|
TemplateListDialogComponent,
|
||||||
UnisolateNodeActionComponent,
|
MoveLayerDownActionComponent,
|
||||||
StopNodeActionComponent,
|
MoveLayerUpActionComponent,
|
||||||
TemplateComponent,
|
EditStyleActionComponent,
|
||||||
TemplateListDialogComponent,
|
EditTextActionComponent,
|
||||||
MoveLayerDownActionComponent,
|
DeleteActionComponent,
|
||||||
MoveLayerUpActionComponent,
|
DuplicateActionComponent,
|
||||||
EditStyleActionComponent,
|
PacketFiltersActionComponent,
|
||||||
EditLinkStyleActionComponent,
|
StartCaptureActionComponent,
|
||||||
EditTextActionComponent,
|
StopCaptureActionComponent,
|
||||||
DeleteActionComponent,
|
ResumeLinkActionComponent,
|
||||||
DuplicateActionComponent,
|
SuspendLinkActionComponent,
|
||||||
PacketFiltersActionComponent,
|
SettingsComponent,
|
||||||
StartCaptureActionComponent,
|
PreferencesComponent,
|
||||||
StopCaptureActionComponent,
|
BundledServerFinderComponent,
|
||||||
ResumeLinkActionComponent,
|
ProgressComponent,
|
||||||
SuspendLinkActionComponent,
|
ServerDiscoveryComponent,
|
||||||
SettingsComponent,
|
NodeSelectInterfaceComponent,
|
||||||
PreferencesComponent,
|
DrawLinkToolComponent,
|
||||||
BundledControllerFinderComponent,
|
InstalledSoftwareComponent,
|
||||||
ProgressComponent,
|
DrawingAddedComponent,
|
||||||
ControllerDiscoveryComponent,
|
DrawingResizedComponent,
|
||||||
NodeSelectInterfaceComponent,
|
TextAddedComponent,
|
||||||
DrawLinkToolComponent,
|
TextEditedComponent,
|
||||||
InstalledSoftwareComponent,
|
NodeDraggedComponent,
|
||||||
DrawingAddedComponent,
|
NodeLabelDraggedComponent,
|
||||||
DrawingResizedComponent,
|
DrawingDraggedComponent,
|
||||||
TextAddedComponent,
|
LinkCreatedComponent,
|
||||||
TextEditedComponent,
|
InterfaceLabelDraggedComponent,
|
||||||
NodeDraggedComponent,
|
InstallSoftwareComponent,
|
||||||
NodeLabelDraggedComponent,
|
StyleEditorDialogComponent,
|
||||||
DrawingDraggedComponent,
|
TextEditorDialogComponent,
|
||||||
LinkCreatedComponent,
|
PacketFiltersDialogComponent,
|
||||||
InterfaceLabelDraggedComponent,
|
QemuPreferencesComponent,
|
||||||
InstallSoftwareComponent,
|
QemuVmTemplatesComponent,
|
||||||
StyleEditorDialogComponent,
|
AddQemuVmTemplateComponent,
|
||||||
LinkStyleEditorDialogComponent,
|
QemuVmTemplateDetailsComponent,
|
||||||
TextEditorDialogComponent,
|
GeneralPreferencesComponent,
|
||||||
PacketFiltersDialogComponent,
|
VpcsPreferencesComponent,
|
||||||
QemuPreferencesComponent,
|
VpcsTemplatesComponent,
|
||||||
QemuVmTemplatesComponent,
|
AddVpcsTemplateComponent,
|
||||||
AddQemuVmTemplateComponent,
|
VpcsTemplateDetailsComponent,
|
||||||
QemuVmTemplateDetailsComponent,
|
VirtualBoxPreferencesComponent,
|
||||||
GeneralPreferencesComponent,
|
VirtualBoxTemplatesComponent,
|
||||||
VpcsPreferencesComponent,
|
VirtualBoxTemplateDetailsComponent,
|
||||||
VpcsTemplatesComponent,
|
AddVirtualBoxTemplateComponent,
|
||||||
AddVpcsTemplateComponent,
|
BuiltInPreferencesComponent,
|
||||||
VpcsTemplateDetailsComponent,
|
EthernetHubsTemplatesComponent,
|
||||||
VirtualBoxPreferencesComponent,
|
EthernetHubsAddTemplateComponent,
|
||||||
VirtualBoxTemplatesComponent,
|
EthernetHubsTemplateDetailsComponent,
|
||||||
VirtualBoxTemplateDetailsComponent,
|
CloudNodesTemplatesComponent,
|
||||||
AddVirtualBoxTemplateComponent,
|
CloudNodesAddTemplateComponent,
|
||||||
BuiltInPreferencesComponent,
|
CloudNodesTemplateDetailsComponent,
|
||||||
EthernetHubsTemplatesComponent,
|
EthernetSwitchesTemplatesComponent,
|
||||||
EthernetHubsAddTemplateComponent,
|
EthernetSwitchesAddTemplateComponent,
|
||||||
EthernetHubsTemplateDetailsComponent,
|
EthernetSwitchesTemplateDetailsComponent,
|
||||||
CloudNodesTemplatesComponent,
|
DynamipsPreferencesComponent,
|
||||||
CloudNodesAddTemplateComponent,
|
IosTemplatesComponent,
|
||||||
CloudNodesTemplateDetailsComponent,
|
IosTemplateDetailsComponent,
|
||||||
EthernetSwitchesTemplatesComponent,
|
AddIosTemplateComponent,
|
||||||
EthernetSwitchesAddTemplateComponent,
|
SymbolsComponent,
|
||||||
EthernetSwitchesTemplateDetailsComponent,
|
VmwarePreferencesComponent,
|
||||||
DynamipsPreferencesComponent,
|
VmwareTemplatesComponent,
|
||||||
IosTemplatesComponent,
|
VmwareTemplateDetailsComponent,
|
||||||
IosTemplateDetailsComponent,
|
AddVmwareTemplateComponent,
|
||||||
AddIosTemplateComponent,
|
DeleteConfirmationDialogComponent,
|
||||||
SymbolsComponent,
|
HelpDialogComponent,
|
||||||
VmwarePreferencesComponent,
|
StartCaptureDialogComponent,
|
||||||
VmwareTemplatesComponent,
|
DeleteTemplateComponent,
|
||||||
VmwareTemplateDetailsComponent,
|
DockerTemplatesComponent,
|
||||||
AddVmwareTemplateComponent,
|
AddDockerTemplateComponent,
|
||||||
DeleteConfirmationDialogComponent,
|
DockerTemplateDetailsComponent,
|
||||||
HelpDialogComponent,
|
IouTemplatesComponent,
|
||||||
StartCaptureDialogComponent,
|
AddIouTemplateComponent,
|
||||||
DeleteTemplateComponent,
|
IouTemplateDetailsComponent,
|
||||||
DockerTemplatesComponent,
|
CopyQemuVmTemplateComponent,
|
||||||
AddDockerTemplateComponent,
|
CopyIosTemplateComponent,
|
||||||
DockerTemplateDetailsComponent,
|
CopyIouTemplateComponent,
|
||||||
IouTemplatesComponent,
|
CopyDockerTemplateComponent,
|
||||||
AddIouTemplateComponent,
|
EmptyTemplatesListComponent,
|
||||||
IouTemplateDetailsComponent,
|
SymbolsMenuComponent,
|
||||||
CopyQemuVmTemplateComponent,
|
SearchFilter,
|
||||||
CopyIosTemplateComponent,
|
DateFilter,
|
||||||
CopyIouTemplateComponent,
|
NameFilter,
|
||||||
CopyDockerTemplateComponent,
|
DataSourceFilter,
|
||||||
EmptyTemplatesListComponent,
|
TemplateFilter,
|
||||||
SymbolsMenuComponent,
|
ProjectsFilter,
|
||||||
SearchFilter,
|
ListOfSnapshotsComponent,
|
||||||
DateFilter,
|
CustomAdaptersComponent,
|
||||||
NameFilter,
|
NodesMenuComponent,
|
||||||
DataSourceFilter,
|
AdbutlerComponent,
|
||||||
TemplateFilter,
|
ConsoleDeviceActionComponent,
|
||||||
ProjectsFilter,
|
ShowNodeActionComponent,
|
||||||
AuthImageFilter,
|
ConsoleComponent,
|
||||||
ListOfSnapshotsComponent,
|
NodesMenuComponent,
|
||||||
CustomAdaptersComponent,
|
ProjectMapMenuComponent,
|
||||||
NodesMenuComponent,
|
HelpComponent,
|
||||||
AdbutlerComponent,
|
ConfigEditorDialogComponent,
|
||||||
ConsoleDeviceActionComponent,
|
EditConfigActionComponent,
|
||||||
ShowNodeActionComponent,
|
LogConsoleComponent,
|
||||||
ConsoleComponent,
|
SaveProjectDialogComponent,
|
||||||
NodesMenuComponent,
|
TopologySummaryComponent,
|
||||||
ProjectMapMenuComponent,
|
InfoDialogComponent,
|
||||||
HelpComponent,
|
BringToFrontActionComponent,
|
||||||
ConfigEditorDialogComponent,
|
ExportConfigActionComponent,
|
||||||
EditConfigActionComponent,
|
ImportConfigActionComponent,
|
||||||
LogConsoleComponent,
|
ConsoleDeviceActionBrowserComponent,
|
||||||
SaveProjectDialogComponent,
|
ChangeSymbolDialogComponent,
|
||||||
TopologySummaryComponent,
|
ChangeSymbolActionComponent,
|
||||||
InfoDialogComponent,
|
EditProjectDialogComponent,
|
||||||
BringToFrontActionComponent,
|
ReloadNodeActionComponent,
|
||||||
ExportConfigActionComponent,
|
SuspendNodeActionComponent,
|
||||||
ImportConfigActionComponent,
|
ConfigActionComponent,
|
||||||
ConsoleDeviceActionBrowserComponent,
|
ConfiguratorDialogVpcsComponent,
|
||||||
ChangeSymbolDialogComponent,
|
ConfiguratorDialogEthernetHubComponent,
|
||||||
ChangeSymbolActionComponent,
|
ConfiguratorDialogEthernetSwitchComponent,
|
||||||
EditProjectDialogComponent,
|
PortsComponent,
|
||||||
ReloadNodeActionComponent,
|
ConfiguratorDialogSwitchComponent,
|
||||||
SuspendNodeActionComponent,
|
ConfiguratorDialogVirtualBoxComponent,
|
||||||
ConfigActionComponent,
|
CustomAdaptersTableComponent,
|
||||||
ConfiguratorDialogVpcsComponent,
|
ConfiguratorDialogQemuComponent,
|
||||||
ConfiguratorDialogEthernetHubComponent,
|
ConfiguratorDialogCloudComponent,
|
||||||
ConfiguratorDialogEthernetSwitchComponent,
|
UdpTunnelsComponent,
|
||||||
PortsComponent,
|
ConfiguratorDialogAtmSwitchComponent,
|
||||||
ConfiguratorDialogSwitchComponent,
|
ConfiguratorDialogVmwareComponent,
|
||||||
ConfiguratorDialogVirtualBoxComponent,
|
ConfiguratorDialogIouComponent,
|
||||||
CustomAdaptersTableComponent,
|
ConfiguratorDialogIosComponent,
|
||||||
ConfiguratorDialogQemuComponent,
|
ConfiguratorDialogDockerComponent,
|
||||||
ConfiguratorDialogCloudComponent,
|
ConfiguratorDialogNatComponent,
|
||||||
UdpTunnelsComponent,
|
ConfiguratorDialogTracengComponent,
|
||||||
ConfiguratorDialogAtmSwitchComponent,
|
AddTracengTemplateComponent,
|
||||||
ConfiguratorDialogVmwareComponent,
|
TracengPreferencesComponent,
|
||||||
ConfiguratorDialogIouComponent,
|
TracengTemplatesComponent,
|
||||||
ConfiguratorDialogIosComponent,
|
TracengTemplateDetailsComponent,
|
||||||
ConfiguratorDialogDockerComponent,
|
QemuImageCreatorComponent,
|
||||||
ConfiguratorDialogNatComponent,
|
ChooseNameDialogComponent,
|
||||||
QemuImageCreatorComponent,
|
StartCaptureOnStartedLinkActionComponent,
|
||||||
ChooseNameDialogComponent,
|
LockActionComponent,
|
||||||
StartCaptureOnStartedLinkActionComponent,
|
NavigationDialogComponent,
|
||||||
LockActionComponent,
|
ScreenshotDialogComponent,
|
||||||
NavigationDialogComponent,
|
PageNotFoundComponent,
|
||||||
ScreenshotDialogComponent,
|
AlignHorizontallyActionComponent,
|
||||||
PageNotFoundComponent,
|
AlignVerticallyActionComponent,
|
||||||
AlignHorizontallyActionComponent,
|
ConfirmationBottomSheetComponent,
|
||||||
AlignVerticallyActionComponent,
|
ConfigDialogComponent,
|
||||||
ConfirmationBottomSheetComponent,
|
Gns3vmComponent,
|
||||||
ConfigDialogComponent,
|
ConfigureGns3VMDialogComponent,
|
||||||
ImportApplianceComponent,
|
ImportApplianceComponent,
|
||||||
DirectLinkComponent,
|
DirectLinkComponent,
|
||||||
SystemStatusComponent,
|
SystemStatusComponent,
|
||||||
StatusInfoComponent,
|
StatusInfoComponent,
|
||||||
StatusChartComponent,
|
StatusChartComponent,
|
||||||
OpenFileExplorerActionComponent,
|
OpenFileExplorerActionComponent,
|
||||||
HttpConsoleActionComponent,
|
HttpConsoleActionComponent,
|
||||||
WebConsoleComponent,
|
WebConsoleComponent,
|
||||||
ConsoleWrapperComponent,
|
ConsoleWrapperComponent,
|
||||||
HttpConsoleNewTabActionComponent,
|
HttpConsoleNewTabActionComponent,
|
||||||
WebConsoleFullWindowComponent,
|
WebConsoleFullWindowComponent,
|
||||||
NewTemplateDialogComponent,
|
NewTemplateDialogComponent,
|
||||||
ChangeHostnameActionComponent,
|
ChangeHostnameActionComponent,
|
||||||
ChangeHostnameDialogComponent,
|
ChangeHostnameDialogComponent,
|
||||||
ApplianceInfoDialogComponent,
|
ApplianceInfoDialogComponent,
|
||||||
ReadmeEditorComponent,
|
InformationDialogComponent,
|
||||||
MarkedDirective,
|
TemplateNameDialogComponent,
|
||||||
InformationDialogComponent,
|
ConfigureCustomAdaptersDialogComponent,
|
||||||
TemplateNameDialogComponent,
|
EditNetworkConfigurationDialogComponent
|
||||||
ConfigureCustomAdaptersDialogComponent,
|
],
|
||||||
EditNetworkConfigurationDialogComponent,
|
imports: [
|
||||||
UserManagementComponent,
|
BrowserModule,
|
||||||
ProjectReadmeComponent,
|
HttpClientModule,
|
||||||
AddGroupDialogComponent,
|
AppRoutingModule,
|
||||||
GroupFilterPipe,
|
FormsModule,
|
||||||
GroupManagementComponent,
|
ReactiveFormsModule,
|
||||||
AddUserDialogComponent,
|
BrowserAnimationsModule,
|
||||||
UserFilterPipe,
|
CdkTableModule,
|
||||||
DeleteGroupDialogComponent,
|
CartographyModule,
|
||||||
DeleteUserDialogComponent,
|
NgxElectronModule,
|
||||||
GroupDetailsComponent,
|
FileUploadModule,
|
||||||
UserDetailComponent,
|
MatSidenavModule,
|
||||||
AddUserToGroupDialogComponent,
|
ResizableModule,
|
||||||
RemoveToGroupDialogComponent,
|
DragAndDropModule,
|
||||||
PaginatorPipe,
|
DragDropModule,
|
||||||
MembersFilterPipe,
|
NgxChildProcessModule,
|
||||||
ManagementComponent,
|
MATERIAL_IMPORTS,
|
||||||
RoleManagementComponent,
|
NgCircleProgressModule.forRoot(),
|
||||||
RoleFilterPipe,
|
OverlayModule,
|
||||||
AddRoleDialogComponent,
|
],
|
||||||
DeleteRoleDialogComponent,
|
providers: [
|
||||||
RoleDetailComponent,
|
SettingsService,
|
||||||
RemoveToGroupDialogComponent,
|
{ provide: ErrorHandler, useClass: ToasterErrorHandler },
|
||||||
AddRoleToGroupComponent,
|
D3Service,
|
||||||
ChangeUserPasswordComponent,
|
VersionService,
|
||||||
ChangeUserPasswordComponent,
|
ProjectService,
|
||||||
ProjectReadmeComponent,
|
SymbolService,
|
||||||
ImageManagerComponent,
|
ServerService,
|
||||||
AddImageDialogComponent,
|
TemplateService,
|
||||||
DeleteAllImageFilesDialogComponent,
|
NodeService,
|
||||||
UploadingProcessbarComponent,
|
LinkService,
|
||||||
ExportPortableProjectComponent,
|
DrawingService,
|
||||||
NodesMenuConfirmationDialogComponent,
|
HttpServer,
|
||||||
ConfirmationDeleteAllProjectsComponent,
|
SnapshotService,
|
||||||
ProjectMapLockConfirmationDialogComponent,
|
ProgressDialogService,
|
||||||
AclManagementComponent,
|
ToasterService,
|
||||||
AddAceDialogComponent,
|
ProgressService,
|
||||||
AutocompleteComponent,
|
ProjectWebServiceHandler,
|
||||||
DeleteAceDialogComponent,
|
LinksDataSource,
|
||||||
AceFilterPipe,
|
NodesDataSource,
|
||||||
PrivilegeComponent,
|
SymbolsDataSource,
|
||||||
GroupPrivilegesPipe,
|
LogEventsDataSource,
|
||||||
ResourcePoolsManagementComponent,
|
SelectionManager,
|
||||||
AddResourcePoolDialogComponent,
|
InRectangleHelper,
|
||||||
DeleteResourcePoolComponent,
|
DrawingsDataSource,
|
||||||
ResourcePoolsFilterPipe,
|
ServerErrorHandler,
|
||||||
ResourcePoolDetailsComponent,
|
ServerDatabase,
|
||||||
DeleteResourceConfirmationDialogComponent,
|
ProjectNameValidator,
|
||||||
],
|
ToolsService,
|
||||||
imports: [
|
ServerSettingsService,
|
||||||
BrowserModule,
|
QemuService,
|
||||||
HttpClientModule,
|
VpcsService,
|
||||||
AppRoutingModule,
|
TemplateMocksService,
|
||||||
FormsModule,
|
VirtualBoxService,
|
||||||
ReactiveFormsModule,
|
BuiltInTemplatesService,
|
||||||
BrowserAnimationsModule,
|
IosService,
|
||||||
CdkTableModule,
|
InstalledSoftwareService,
|
||||||
CartographyModule,
|
ExternalSoftwareDefinitionService,
|
||||||
NgxElectronModule,
|
PlatformService,
|
||||||
FileUploadModule,
|
IosConfigurationService,
|
||||||
MatSidenavModule,
|
QemuConfigurationService,
|
||||||
MatFormFieldModule,
|
VirtualBoxConfigurationService,
|
||||||
MatMenuModule,
|
VpcsConfigurationService,
|
||||||
ResizableModule,
|
BuiltInTemplatesConfigurationService,
|
||||||
DragAndDropModule,
|
VmwareService,
|
||||||
DragDropModule,
|
VmwareConfigurationService,
|
||||||
NgxChildProcessModule,
|
DockerService,
|
||||||
MATERIAL_IMPORTS,
|
DockerConfigurationService,
|
||||||
NgCircleProgressModule.forRoot(),
|
IouService,
|
||||||
OverlayModule,
|
IouConfigurationService,
|
||||||
MatSlideToggleModule,
|
RecentlyOpenedProjectService,
|
||||||
MatCheckboxModule,
|
ServerManagementService,
|
||||||
MatAutocompleteModule,
|
MapScaleService,
|
||||||
CdkAccordionModule,
|
ConsoleService,
|
||||||
CdkTreeModule,
|
DefaultConsoleService,
|
||||||
],
|
NodeCreatedLabelStylesFixer,
|
||||||
providers: [
|
NonNegativeValidator,
|
||||||
SettingsService,
|
RotationValidator,
|
||||||
{ provide: ErrorHandler, useClass: ToasterErrorHandler },
|
MapSettingsService,
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpRequestsInterceptor, multi: true },
|
InfoService,
|
||||||
VersionService,
|
ComputeService,
|
||||||
D3Service,
|
TracengService,
|
||||||
ProjectService,
|
PacketCaptureService,
|
||||||
SymbolService,
|
ProtocolHandlerService,
|
||||||
ControllerService,
|
NotificationService,
|
||||||
TemplateService,
|
Gns3vmService,
|
||||||
NodeService,
|
ThemeService,
|
||||||
LinkService,
|
GoogleAnalyticsService,
|
||||||
DrawingService,
|
NodeConsoleService,
|
||||||
HttpController,
|
ServerResolve,
|
||||||
SnapshotService,
|
ConsoleGuard,
|
||||||
ProgressDialogService,
|
Title,
|
||||||
ToasterService,
|
ApplianceService,
|
||||||
ProgressService,
|
UpdatesService,
|
||||||
ProjectWebServiceHandler,
|
],
|
||||||
LinksDataSource,
|
entryComponents: [
|
||||||
NodesDataSource,
|
AddServerDialogComponent,
|
||||||
SymbolsDataSource,
|
CreateSnapshotDialogComponent,
|
||||||
LogEventsDataSource,
|
ProgressDialogComponent,
|
||||||
SelectionManager,
|
TemplateListDialogComponent,
|
||||||
InRectangleHelper,
|
AddBlankProjectDialogComponent,
|
||||||
DrawingsDataSource,
|
ImportProjectDialogComponent,
|
||||||
ControllerErrorHandler,
|
ConfirmationDialogComponent,
|
||||||
ControllerDatabase,
|
StyleEditorDialogComponent,
|
||||||
ProjectNameValidator,
|
PacketFiltersDialogComponent,
|
||||||
ToolsService,
|
TextEditorDialogComponent,
|
||||||
ControllerSettingsService,
|
SymbolsComponent,
|
||||||
QemuService,
|
DeleteConfirmationDialogComponent,
|
||||||
VpcsService,
|
HelpDialogComponent,
|
||||||
TemplateMocksService,
|
StartCaptureDialogComponent,
|
||||||
VirtualBoxService,
|
ConfigEditorDialogComponent,
|
||||||
BuiltInTemplatesService,
|
SaveProjectDialogComponent,
|
||||||
IosService,
|
InfoDialogComponent,
|
||||||
InstalledSoftwareService,
|
ChangeSymbolDialogComponent,
|
||||||
ExternalSoftwareDefinitionService,
|
EditProjectDialogComponent,
|
||||||
PlatformService,
|
ConfigureGns3VMDialogComponent,
|
||||||
IosConfigurationService,
|
ConfiguratorDialogVpcsComponent,
|
||||||
QemuConfigurationService,
|
ConfiguratorDialogEthernetHubComponent,
|
||||||
VirtualBoxConfigurationService,
|
ConfiguratorDialogEthernetSwitchComponent,
|
||||||
VpcsConfigurationService,
|
ConfiguratorDialogSwitchComponent,
|
||||||
BuiltInTemplatesConfigurationService,
|
ConfiguratorDialogVirtualBoxComponent,
|
||||||
VmwareService,
|
ConfiguratorDialogQemuComponent,
|
||||||
VmwareConfigurationService,
|
ConfiguratorDialogCloudComponent,
|
||||||
DockerService,
|
ConfiguratorDialogAtmSwitchComponent,
|
||||||
DockerConfigurationService,
|
ConfiguratorDialogVmwareComponent,
|
||||||
IouService,
|
ConfiguratorDialogIouComponent,
|
||||||
IouConfigurationService,
|
ConfiguratorDialogIosComponent,
|
||||||
RecentlyOpenedProjectService,
|
ConfiguratorDialogDockerComponent,
|
||||||
ControllerManagementService,
|
ConfiguratorDialogNatComponent,
|
||||||
MapScaleService,
|
ConfiguratorDialogTracengComponent,
|
||||||
ConsoleService,
|
QemuImageCreatorComponent,
|
||||||
DefaultConsoleService,
|
ChooseNameDialogComponent,
|
||||||
NodeCreatedLabelStylesFixer,
|
NavigationDialogComponent,
|
||||||
NonNegativeValidator,
|
ScreenshotDialogComponent,
|
||||||
RotationValidator,
|
ConfirmationBottomSheetComponent,
|
||||||
MapSettingsService,
|
ConfigDialogComponent,
|
||||||
InfoService,
|
AdbutlerComponent,
|
||||||
ComputeService,
|
NewTemplateDialogComponent,
|
||||||
PacketCaptureService,
|
ChangeHostnameDialogComponent,
|
||||||
NotificationService,
|
ApplianceInfoDialogComponent,
|
||||||
ThemeService,
|
ConfigureCustomAdaptersDialogComponent,
|
||||||
GoogleAnalyticsService,
|
EditNetworkConfigurationDialogComponent,
|
||||||
NodeConsoleService,
|
],
|
||||||
ControllerResolve,
|
bootstrap: [AppComponent],
|
||||||
LoginGuard,
|
|
||||||
ConsoleGuard,
|
|
||||||
Title,
|
|
||||||
ApplianceService,
|
|
||||||
UpdatesService,
|
|
||||||
LoginService,
|
|
||||||
UserService
|
|
||||||
],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
constructor(protected _googleAnalyticsService: GoogleAnalyticsService) {}
|
constructor(protected _googleAnalyticsService: GoogleAnalyticsService) {}
|
||||||
|
@ -5,7 +5,6 @@ import { MatMenuModule } from '@angular/material/menu';
|
|||||||
import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports';
|
import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports';
|
||||||
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
||||||
import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component';
|
import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component';
|
||||||
import { LinkEditingComponent } from './components/link-editing/link-editing.component';
|
|
||||||
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
||||||
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
||||||
import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component';
|
import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component';
|
||||||
@ -74,7 +73,6 @@ import { SerialLinkWidget } from './widgets/links/serial-link';
|
|||||||
SelectionControlComponent,
|
SelectionControlComponent,
|
||||||
SelectionSelectComponent,
|
SelectionSelectComponent,
|
||||||
DraggableSelectionComponent,
|
DraggableSelectionComponent,
|
||||||
LinkEditingComponent,
|
|
||||||
MovingCanvasDirective,
|
MovingCanvasDirective,
|
||||||
ZoomingCanvasDirective,
|
ZoomingCanvasDirective,
|
||||||
],
|
],
|
||||||
|
@ -44,6 +44,5 @@
|
|||||||
<app-drawing-resizing></app-drawing-resizing>
|
<app-drawing-resizing></app-drawing-resizing>
|
||||||
<app-selection-control></app-selection-control>
|
<app-selection-control></app-selection-control>
|
||||||
<app-selection-select></app-selection-select>
|
<app-selection-select></app-selection-select>
|
||||||
<app-text-editor #textEditor [controller]="controller" [svg]="svg"></app-text-editor>
|
<app-text-editor #textEditor [server]="server" [svg]="svg"></app-text-editor>
|
||||||
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
||||||
<app-link-editing [svg]="svg"></app-link-editing>
|
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1,17 +1,23 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { D3MapComponent } from './d3-map.component';
|
import { D3MapComponent } from './d3-map.component';
|
||||||
|
|
||||||
describe('D3MapComponent', () => {
|
describe('D3MapComponent', () => {
|
||||||
let component: D3MapComponent;
|
let component: D3MapComponent;
|
||||||
let fixture: ComponentFixture<D3MapComponent>;
|
let fixture: ComponentFixture<D3MapComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [D3MapComponent],
|
declarations: [D3MapComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
it('should create', () => {
|
// beforeEach(() => {
|
||||||
expect(component)
|
// fixture = TestBed.createComponent(MapComponent);
|
||||||
});
|
// component = fixture.componentInstance;
|
||||||
|
// fixture.detectChanges();
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// it('should create', () => {
|
||||||
|
// expect(component).toBeTruthy();
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,7 @@ import { select, Selection } from 'd3-selection';
|
|||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { Link } from '../../../models/link';
|
import { Link } from '../../../models/link';
|
||||||
import { Project } from '../../../models/project';
|
import { Project } from '../../../models/project';
|
||||||
import { Controller } from '../../../models/controller';
|
import { Server } from '../../../models/server';
|
||||||
import { Symbol } from '../../../models/symbol';
|
import { Symbol } from '../../../models/symbol';
|
||||||
import { MapScaleService } from '../../../services/mapScale.service';
|
import { MapScaleService } from '../../../services/mapScale.service';
|
||||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||||
@ -43,7 +43,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Input() drawings: Drawing[] = [];
|
@Input() drawings: Drawing[] = [];
|
||||||
@Input() symbols: Symbol[] = [];
|
@Input() symbols: Symbol[] = [];
|
||||||
@Input() project: Project;
|
@Input() project: Project;
|
||||||
@Input() controller: Controller;
|
@Input() server: Server;
|
||||||
|
|
||||||
@Input() width = 1500;
|
@Input() width = 1500;
|
||||||
@Input() height = 600;
|
@Input() height = 600;
|
||||||
|
@ -42,7 +42,7 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
let interfaceLabelDragEventEmitter: EventEmitter<DraggableDrag<MapLinkNode>>;
|
let interfaceLabelDragEventEmitter: EventEmitter<DraggableDrag<MapLinkNode>>;
|
||||||
let interfaceLabelEndEventEmitter: EventEmitter<DraggableEnd<MapLinkNode>>;
|
let interfaceLabelEndEventEmitter: EventEmitter<DraggableEnd<MapLinkNode>>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async(() => {
|
||||||
mockedGraphDataManager = new MockedGraphDataManager();
|
mockedGraphDataManager = new MockedGraphDataManager();
|
||||||
|
|
||||||
nodesStartEventEmitter = new EventEmitter<DraggableStart<MapNode>>();
|
nodesStartEventEmitter = new EventEmitter<DraggableStart<MapNode>>();
|
||||||
@ -110,7 +110,7 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
interfaceDragged: { emit: () => {} },
|
interfaceDragged: { emit: () => {} },
|
||||||
};
|
};
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: NodesWidget, useValue: nodesWidgetStub },
|
{ provide: NodesWidget, useValue: nodesWidgetStub },
|
||||||
{ provide: DrawingsWidget, useValue: drawingsWidgetStub },
|
{ provide: DrawingsWidget, useValue: drawingsWidgetStub },
|
||||||
@ -126,7 +126,7 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
],
|
],
|
||||||
declarations: [DraggableSelectionComponent],
|
declarations: [DraggableSelectionComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DraggableSelectionComponent);
|
fixture = TestBed.createComponent(DraggableSelectionComponent);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { Context } from '../../models/context';
|
import { Context } from '../../models/context';
|
||||||
@ -9,8 +9,8 @@ describe('DrawingAddingComponent', () => {
|
|||||||
let fixture: ComponentFixture<DrawingAddingComponent>;
|
let fixture: ComponentFixture<DrawingAddingComponent>;
|
||||||
let drawingsEventSource = new DrawingsEventSource();
|
let drawingsEventSource = new DrawingsEventSource();
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||||
@ -18,7 +18,7 @@ describe('DrawingAddingComponent', () => {
|
|||||||
],
|
],
|
||||||
declarations: [DrawingAddingComponent],
|
declarations: [DrawingAddingComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DrawingAddingComponent);
|
fixture = TestBed.createComponent(DrawingAddingComponent);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { EventEmitter } from '@angular/core';
|
import { EventEmitter } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { ResizingEnd } from '../../events/resizing';
|
import { ResizingEnd } from '../../events/resizing';
|
||||||
@ -30,8 +30,8 @@ describe('DrawingResizingComponent', () => {
|
|||||||
let drawingsWidgetMock = new DrawingWidgetMock();
|
let drawingsWidgetMock = new DrawingWidgetMock();
|
||||||
let drawingsEventSource = new DrawingsEventSource();
|
let drawingsEventSource = new DrawingsEventSource();
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
||||||
@ -39,7 +39,7 @@ describe('DrawingResizingComponent', () => {
|
|||||||
],
|
],
|
||||||
declarations: [DrawingResizingComponent],
|
declarations: [DrawingResizingComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DrawingResizingComponent);
|
fixture = TestBed.createComponent(DrawingResizingComponent);
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { DraggableComponent } from './draggable.component';
|
import { DraggableComponent } from './draggable.component';
|
||||||
|
|
||||||
describe('DraggableComponent', () => {
|
describe('DraggableComponent', () => {
|
||||||
let component: DraggableComponent;
|
let component: DraggableComponent;
|
||||||
let fixture: ComponentFixture<DraggableComponent>;
|
let fixture: ComponentFixture<DraggableComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [DraggableComponent],
|
declarations: [DraggableComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DraggableComponent);
|
fixture = TestBed.createComponent(DraggableComponent);
|
||||||
@ -17,7 +17,7 @@ describe('DraggableComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
(dragging)="OnDragging($event)"
|
(dragging)="OnDragging($event)"
|
||||||
(dragged)="OnDragged($event)"
|
(dragged)="OnDragged($event)"
|
||||||
>
|
>
|
||||||
<svg:g *ngIf="is(drawing?.element, 'ellipse')" [app-ellipse]="drawing?.element" />
|
<svg:g *ngIf="is(drawing.element, 'ellipse')" [app-ellipse]="drawing.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing?.element, 'image')" [app-image]="drawing?.element" />
|
<svg:g *ngIf="is(drawing.element, 'image')" [app-image]="drawing.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing?.element, 'line')" [app-line]="drawing?.element" />
|
<svg:g *ngIf="is(drawing.element, 'line')" [app-line]="drawing.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing?.element, 'rect')" [app-rect]="drawing?.element" />
|
<svg:g *ngIf="is(drawing.element, 'rect')" [app-rect]="drawing.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing?.element, 'text')" [app-text]="drawing?.element" />
|
<svg:g *ngIf="is(drawing.element, 'text')" [app-text]="drawing.element" />
|
||||||
</svg:g>
|
</svg:g>
|
||||||
|
Before Width: | Height: | Size: 573 B After Width: | Height: | Size: 563 B |
@ -1,18 +1,15 @@
|
|||||||
import {ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { DrawingsEventSource } from 'app/cartography/events/drawings-event-source';
|
|
||||||
import { SvgToDrawingConverter } from 'app/cartography/helpers/svg-to-drawing-converter';
|
|
||||||
import { DrawingComponent } from './drawing.component';
|
import { DrawingComponent } from './drawing.component';
|
||||||
|
|
||||||
describe('DrawingComponent', () => {
|
describe('DrawingComponent', () => {
|
||||||
let component: DrawingComponent;
|
let component: DrawingComponent;
|
||||||
let fixture: ComponentFixture<DrawingComponent>;
|
let fixture: ComponentFixture<DrawingComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [DrawingComponent],
|
declarations: [DrawingComponent],
|
||||||
providers:[SvgToDrawingConverter,DrawingsEventSource]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DrawingComponent);
|
fixture = TestBed.createComponent(DrawingComponent);
|
||||||
@ -20,7 +17,7 @@ describe('DrawingComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -21,17 +21,17 @@ export class DrawingComponent implements OnInit {
|
|||||||
private svgToDrawingConverter: SvgToDrawingConverter,
|
private svgToDrawingConverter: SvgToDrawingConverter,
|
||||||
private drawingsEventSource: DrawingsEventSource,
|
private drawingsEventSource: DrawingsEventSource,
|
||||||
private cd: ChangeDetectorRef
|
private cd: ChangeDetectorRef
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
try {
|
try {
|
||||||
this.drawing.element = this.svgToDrawingConverter.convert(this.drawing.svg);
|
this.drawing.element = this.svgToDrawingConverter.convert(this.drawing.svg);
|
||||||
} catch (error) { }
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnDragging(evt) {
|
OnDragging(evt) {
|
||||||
this.drawing.x = evt ? evt.x : '';
|
this.drawing.x = evt.x;
|
||||||
this.drawing.y = evt ? evt.y : '';
|
this.drawing.y = evt.y;
|
||||||
this.cd.detectChanges();
|
this.cd.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,8 +64,6 @@ export class DrawingComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get transformation() {
|
get transformation() {
|
||||||
if (this.drawing) {
|
return `translate(${this.drawing.x},${this.drawing.y}) rotate(${this.drawing.rotation})`;
|
||||||
return `translate(${this.drawing.x},${this.drawing.y}) rotate(${this.drawing.rotation})`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<svg:ellipse
|
<svg:ellipse
|
||||||
class="ellipse_element noselect"
|
class="ellipse_element noselect"
|
||||||
[attr.fill]="ellipse?.fill"
|
[attr.fill]="ellipse.fill"
|
||||||
[attr.fill-opacity]="fill_opacity"
|
[attr.fill-opacity]="fill_opacity"
|
||||||
[attr.stroke]="ellipse?.stroke"
|
[attr.stroke]="ellipse.stroke"
|
||||||
[attr.stroke-width]="stroke_width"
|
[attr.stroke-width]="stroke_width"
|
||||||
[attr.stroke-dasharray]="stroke_dasharray"
|
[attr.stroke-dasharray]="stroke_dasharray"
|
||||||
[attr.cx]="ellipse?.cx"
|
[attr.cx]="ellipse.cx"
|
||||||
[attr.cy]="ellipse?.cy"
|
[attr.cy]="ellipse.cy"
|
||||||
[attr.rx]="ellipse?.rx"
|
[attr.rx]="ellipse.rx"
|
||||||
[attr.ry]="ellipse?.ry"
|
[attr.ry]="ellipse.ry"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 332 B |
@ -1,17 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { QtDasharrayFixer } from 'app/cartography/helpers/qt-dasharray-fixer';
|
|
||||||
import { EllipseComponent } from './ellipse.component';
|
import { EllipseComponent } from './ellipse.component';
|
||||||
|
|
||||||
describe('EllipseComponent', () => {
|
describe('EllipseComponent', () => {
|
||||||
let component: EllipseComponent;
|
let component: EllipseComponent;
|
||||||
let fixture: ComponentFixture<EllipseComponent>;
|
let fixture: ComponentFixture<EllipseComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [EllipseComponent],
|
declarations: [EllipseComponent],
|
||||||
providers:[QtDasharrayFixer]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(EllipseComponent);
|
fixture = TestBed.createComponent(EllipseComponent);
|
||||||
@ -19,7 +17,7 @@ describe('EllipseComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -15,21 +15,21 @@ export class EllipseComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
get fill_opacity() {
|
get fill_opacity() {
|
||||||
if (this.ellipse && isFinite(this.ellipse.fill_opacity)) {
|
if (isFinite(this.ellipse.fill_opacity)) {
|
||||||
return this.ellipse.fill_opacity;
|
return this.ellipse.fill_opacity;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_width() {
|
get stroke_width() {
|
||||||
if (this.ellipse && isFinite(this.ellipse.stroke_width)) {
|
if (isFinite(this.ellipse.stroke_width)) {
|
||||||
return this.ellipse.stroke_width;
|
return this.ellipse.stroke_width;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_dasharray() {
|
get stroke_dasharray() {
|
||||||
if (this.ellipse && this.ellipse.stroke_dasharray) {
|
if (this.ellipse.stroke_dasharray) {
|
||||||
return this.qtDasharrayFixer.fix(this.ellipse.stroke_dasharray);
|
return this.qtDasharrayFixer.fix(this.ellipse.stroke_dasharray);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<svg:image
|
<svg:image
|
||||||
class="image_element noselect"
|
class="image_element noselect"
|
||||||
[attr.xlink:href]="image?.data"
|
[attr.xlink:href]="image.data"
|
||||||
[attr.width]="image?.width"
|
[attr.width]="image.width"
|
||||||
[attr.height]="image?.height"
|
[attr.height]="image.height"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 140 B |
@ -1,15 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ImageComponent } from './image.component';
|
import { ImageComponent } from './image.component';
|
||||||
|
|
||||||
describe('ImageComponent', () => {
|
describe('ImageComponent', () => {
|
||||||
let component: ImageComponent;
|
let component: ImageComponent;
|
||||||
let fixture: ComponentFixture<ImageComponent>;
|
let fixture: ComponentFixture<ImageComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ImageComponent],
|
declarations: [ImageComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ImageComponent);
|
fixture = TestBed.createComponent(ImageComponent);
|
||||||
@ -17,7 +17,7 @@ describe('ImageComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,6 @@ import { ImageElement } from '../../../../../models/drawings/image-element';
|
|||||||
})
|
})
|
||||||
export class ImageComponent implements OnInit {
|
export class ImageComponent implements OnInit {
|
||||||
@Input('app-image') image: ImageElement;
|
@Input('app-image') image: ImageElement;
|
||||||
data:any
|
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<svg:line
|
<svg:line
|
||||||
class="line_element noselect"
|
class="line_element noselect"
|
||||||
[attr.stroke]="line?.stroke"
|
[attr.stroke]="line.stroke"
|
||||||
[attr.stroke-width]="stroke_width ?? ''"
|
[attr.stroke-width]="stroke_width"
|
||||||
[attr.stroke-dasharray]="stroke_dasharray"
|
[attr.stroke-dasharray]="stroke_dasharray"
|
||||||
[attr.x1]="line?.x1"
|
[attr.x1]="line.x1"
|
||||||
[attr.x2]="line?.x2"
|
[attr.x2]="line.x2"
|
||||||
[attr.y1]="line?.y1"
|
[attr.y1]="line.y1"
|
||||||
[attr.y2]="line?.y2"
|
[attr.y2]="line.y2"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 245 B |
@ -1,17 +1,15 @@
|
|||||||
import {ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { QtDasharrayFixer } from 'app/cartography/helpers/qt-dasharray-fixer';
|
|
||||||
import { LineComponent } from './line.component';
|
import { LineComponent } from './line.component';
|
||||||
|
|
||||||
describe('LineComponent', () => {
|
describe('LineComponent', () => {
|
||||||
let component: LineComponent;
|
let component: LineComponent;
|
||||||
let fixture: ComponentFixture<LineComponent>;
|
let fixture: ComponentFixture<LineComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [LineComponent],
|
declarations: [LineComponent],
|
||||||
providers:[QtDasharrayFixer]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(LineComponent);
|
fixture = TestBed.createComponent(LineComponent);
|
||||||
@ -19,7 +17,7 @@ describe('LineComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -15,14 +15,14 @@ export class LineComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
get stroke_width() {
|
get stroke_width() {
|
||||||
if (this.line && isFinite(this.line.stroke_width)) {
|
if (isFinite(this.line.stroke_width)) {
|
||||||
return this.line.stroke_width;
|
return this.line.stroke_width;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_dasharray() {
|
get stroke_dasharray() {
|
||||||
if ( this.line && this.line.stroke_dasharray) {
|
if (this.line.stroke_dasharray) {
|
||||||
return this.qtDasharrayFixer.fix(this.line.stroke_dasharray);
|
return this.qtDasharrayFixer.fix(this.line.stroke_dasharray);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<svg:rect
|
<svg:rect
|
||||||
class="rect_element noselect"
|
class="rect_element noselect"
|
||||||
[attr.fill]="rect?.fill"
|
[attr.fill]="rect.fill"
|
||||||
[attr.fill-opacity]="fill_opacity ? fill_opacity : '' "
|
[attr.fill-opacity]="fill_opacity"
|
||||||
[attr.stroke]="rect?.stroke"
|
[attr.stroke]="rect.stroke"
|
||||||
[attr.stroke-width]="stroke_width"
|
[attr.stroke-width]="stroke_width"
|
||||||
[attr.stroke-dasharray]="stroke_dasharray"
|
[attr.stroke-dasharray]="stroke_dasharray"
|
||||||
[attr.width]="rect?.width"
|
[attr.width]="rect.width"
|
||||||
[attr.height]="rect?.height"
|
[attr.height]="rect.height"
|
||||||
[attr.rx]="rect?.rx"
|
[attr.rx]="rect.rx"
|
||||||
[attr.ry]="rect?.ry"
|
[attr.ry]="rect.ry"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 349 B After Width: | Height: | Size: 322 B |
@ -1,17 +1,15 @@
|
|||||||
import {ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { QtDasharrayFixer } from 'app/cartography/helpers/qt-dasharray-fixer';
|
|
||||||
import { RectComponent } from './rect.component';
|
import { RectComponent } from './rect.component';
|
||||||
|
|
||||||
describe('RectComponent', () => {
|
describe('RectComponent', () => {
|
||||||
let component: RectComponent;
|
let component: RectComponent;
|
||||||
let fixture: ComponentFixture<RectComponent>;
|
let fixture: ComponentFixture<RectComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [RectComponent],
|
declarations: [RectComponent],
|
||||||
providers:[QtDasharrayFixer]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(RectComponent);
|
fixture = TestBed.createComponent(RectComponent);
|
||||||
@ -19,7 +17,7 @@ describe('RectComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -15,21 +15,21 @@ export class RectComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
get fill_opacity() {
|
get fill_opacity() {
|
||||||
if (this.rect && isFinite(this.rect.fill_opacity)) {
|
if (isFinite(this.rect.fill_opacity)) {
|
||||||
return this.rect.fill_opacity ? this.rect.fill_opacity : null;
|
return this.rect.fill_opacity;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_width() {
|
get stroke_width() {
|
||||||
if (this.rect && isFinite(this.rect.stroke_width)) {
|
if (isFinite(this.rect.stroke_width)) {
|
||||||
return this.rect.stroke_width ? this.rect.stroke_width : null;
|
return this.rect.stroke_width;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_dasharray() {
|
get stroke_dasharray() {
|
||||||
if (this.rect && this.rect.stroke_dasharray) {
|
if (this.rect.stroke_dasharray) {
|
||||||
return this.qtDasharrayFixer.fix(this.rect.stroke_dasharray);
|
return this.qtDasharrayFixer.fix(this.rect.stroke_dasharray);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class="text_element noselect"
|
class="text_element noselect"
|
||||||
[attr.style]="style"
|
[attr.style]="style"
|
||||||
[attr.text-decoration]="textDecoration"
|
[attr.text-decoration]="textDecoration"
|
||||||
[attr.fill]="text?.fill"
|
[attr.fill]="text.fill"
|
||||||
[attr.transform]="transformation"
|
[attr.transform]="transformation"
|
||||||
>
|
>
|
||||||
<svg:tspan *ngFor="let line of lines; index as i" xml:space="preserve" x="0" [attr.dy]="i == 0 ? '0em' : '1.4em'">
|
<svg:tspan *ngFor="let line of lines; index as i" xml:space="preserve" x="0" [attr.dy]="i == 0 ? '0em' : '1.4em'">
|
||||||
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 338 B |
@ -1,17 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { FontFixer } from 'app/cartography/helpers/font-fixer';
|
|
||||||
import { TextComponent } from './text.component';
|
import { TextComponent } from './text.component';
|
||||||
|
|
||||||
describe('TextComponent', () => {
|
describe('TextComponent', () => {
|
||||||
let component: TextComponent;
|
let component: TextComponent;
|
||||||
let fixture: ComponentFixture<TextComponent>;
|
let fixture: ComponentFixture<TextComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [TextComponent],
|
declarations: [TextComponent],
|
||||||
providers:[FontFixer]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(TextComponent);
|
fixture = TestBed.createComponent(TextComponent);
|
||||||
@ -19,7 +17,7 @@ describe('TextComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -19,12 +19,10 @@ export class TextComponent implements OnInit, DoCheck {
|
|||||||
|
|
||||||
transformation = '';
|
transformation = '';
|
||||||
|
|
||||||
constructor(private fontFixer: FontFixer, private sanitizer: DomSanitizer) { }
|
constructor(private fontFixer: FontFixer, private sanitizer: DomSanitizer) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.text) {
|
this.lines = this.getLines(this.text.text);
|
||||||
this.lines = this.getLines(this.text.text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngDoCheck() {
|
ngDoCheck() {
|
||||||
@ -32,38 +30,32 @@ export class TextComponent implements OnInit, DoCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get style() {
|
get style() {
|
||||||
if (this.text) {
|
const font = this.fontFixer.fix(this.text);
|
||||||
const font = this.fontFixer.fix(this.text);
|
|
||||||
|
|
||||||
const styles: string[] = [];
|
const styles: string[] = [];
|
||||||
if (font.font_family) {
|
if (font.font_family) {
|
||||||
styles.push(`font-family: "${this.text.font_family}"`);
|
styles.push(`font-family: "${this.text.font_family}"`);
|
||||||
}
|
|
||||||
if (font.font_size) {
|
|
||||||
styles.push(`font-size: ${this.text.font_size}pt`);
|
|
||||||
}
|
|
||||||
if (font.font_weight) {
|
|
||||||
styles.push(`font-weight: ${this.text.font_weight}`);
|
|
||||||
}
|
|
||||||
return this.sanitizer.bypassSecurityTrustStyle(styles.join('; '));
|
|
||||||
}
|
}
|
||||||
|
if (font.font_size) {
|
||||||
|
styles.push(`font-size: ${this.text.font_size}pt`);
|
||||||
|
}
|
||||||
|
if (font.font_weight) {
|
||||||
|
styles.push(`font-weight: ${this.text.font_weight}`);
|
||||||
|
}
|
||||||
|
return this.sanitizer.bypassSecurityTrustStyle(styles.join('; '));
|
||||||
}
|
}
|
||||||
|
|
||||||
get textDecoration() {
|
get textDecoration() {
|
||||||
if (this.text) {
|
return this.text.text_decoration;
|
||||||
return this.text.text_decoration;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateTransformation() {
|
calculateTransformation() {
|
||||||
if (this.textRef != undefined) {
|
const tspans = this.textRef.nativeElement.getElementsByTagName('tspan');
|
||||||
const tspans = this.textRef.nativeElement.getElementsByTagName('tspan');
|
if (tspans.length > 0) {
|
||||||
if (tspans.length > 0) {
|
const height = this.textRef.nativeElement.getBBox().height / tspans.length;
|
||||||
const height = this.textRef.nativeElement.getBBox().height / tspans.length;
|
return `translate(${TextComponent.MARGIN}, ${height - TextComponent.MARGIN})`;
|
||||||
return `translate(${TextComponent.MARGIN}, ${height - TextComponent.MARGIN})`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
getLines(text: string) {
|
getLines(text: string) {
|
||||||
|
@ -1,28 +1,15 @@
|
|||||||
import { ChangeDetectorRef, ElementRef, Injectable } from '@angular/core';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { CssFixer } from 'app/cartography/helpers/css-fixer';
|
|
||||||
import { InterfaceLabelComponent } from './interface-label.component';
|
import { InterfaceLabelComponent } from './interface-label.component';
|
||||||
|
|
||||||
export class MockElementRef extends ElementRef {
|
describe('InterfaceLabelComponent', () => {
|
||||||
constructor() { super(null || undefined); }
|
|
||||||
nativeElement={}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xdescribe('InterfaceLabelComponent', () => {
|
|
||||||
let component: InterfaceLabelComponent;
|
let component: InterfaceLabelComponent;
|
||||||
let fixture: ComponentFixture<InterfaceLabelComponent>;
|
let fixture: ComponentFixture<InterfaceLabelComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [InterfaceLabelComponent],
|
declarations: [InterfaceLabelComponent],
|
||||||
providers: [
|
|
||||||
CssFixer,
|
|
||||||
ChangeDetectorRef,
|
|
||||||
{ provide: ElementRef, useValue: new MockElementRef() },
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(InterfaceLabelComponent);
|
fixture = TestBed.createComponent(InterfaceLabelComponent);
|
||||||
@ -30,7 +17,7 @@ xdescribe('InterfaceLabelComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy()
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -30,9 +30,9 @@ export class InterfaceLabelComponent implements OnInit {
|
|||||||
private ref: ChangeDetectorRef,
|
private ref: ChangeDetectorRef,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private cssFixer: CssFixer
|
private cssFixer: CssFixer
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
ngOnInit() { }
|
ngOnInit() {}
|
||||||
|
|
||||||
@Input('x')
|
@Input('x')
|
||||||
set x(value) {
|
set x(value) {
|
||||||
@ -89,11 +89,9 @@ export class InterfaceLabelComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get transform() {
|
get transform() {
|
||||||
if (this.elementRef.nativeElement.getBBox) {
|
const bbox = this.elementRef.nativeElement.getBBox();
|
||||||
const bbox = this.elementRef.nativeElement.getBBox()
|
const x = this.label.x;
|
||||||
const x = this.label.x;
|
const y = this.label.y + bbox.height;
|
||||||
const y = this.label.y + bbox.height;
|
return `translate(${x}, ${y}) rotate(${this.label.rotation}, ${x}, ${y})`;
|
||||||
return `translate(${x}, ${y}) rotate(${this.label.rotation}, ${x}, ${y})`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<svg:g
|
<svg:g
|
||||||
class="link"
|
class="link"
|
||||||
[attr.link_id]="link?.id"
|
[attr.link_id]="link.id"
|
||||||
[attr.map-source]="link?.source?.id"
|
[attr.map-source]="link.source.id"
|
||||||
[attr.map-target]="link?.target?.id"
|
[attr.map-target]="link.target.id"
|
||||||
[attr.transform]="transform"
|
[attr.transform]="transform"
|
||||||
>
|
>
|
||||||
<svg:path
|
<svg:path
|
||||||
#path
|
#path
|
||||||
*ngIf="link?.linkType == 'ethernet'"
|
*ngIf="link.linkType == 'ethernet'"
|
||||||
class="ethernet_link"
|
class="ethernet_link"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<svg:path
|
<svg:path
|
||||||
#path
|
#path
|
||||||
*ngIf="link?.linkType == 'serial'"
|
*ngIf="link.linkType == 'serial'"
|
||||||
class="serial_link"
|
class="serial_link"
|
||||||
stroke="#B22222"
|
stroke="#B22222"
|
||||||
fill="none"
|
fill="none"
|
||||||
@ -24,27 +24,27 @@
|
|||||||
[attr.d]="d"
|
[attr.d]="d"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<svg:g [app-status]="link?.source?.status" [direction]="'source'" [path]="path" [d]="d" />
|
<svg:g [app-status]="link.source.status" [direction]="'source'" [path]="path" [d]="d" />
|
||||||
|
|
||||||
<svg:g [app-status]="link?.target?.status" [direction]="'target'" [path]="path" [d]="d" />
|
<svg:g [app-status]="link.target.status" [direction]="'target'" [path]="path" [d]="d" />
|
||||||
|
|
||||||
<svg:g
|
<svg:g
|
||||||
*ngIf="showInterfaceLabels"
|
*ngIf="showInterfaceLabels"
|
||||||
[app-interface-label]
|
[app-interface-label]
|
||||||
[x]="link?.source?.x + link?.nodes[0]?.label?.x"
|
[x]="link.source.x + link.nodes[0].label.x"
|
||||||
[y]="link?.source?.y + link?.nodes[0]?.label?.y"
|
[y]="link.source.y + link.nodes[0].label.y"
|
||||||
[text]="link?.nodes[0]?.label?.text"
|
[text]="link.nodes[0].label.text"
|
||||||
[style]="link?.nodes[0]?.label?.style"
|
[style]="link.nodes[0].label.style"
|
||||||
[rotation]="link?.nodes[0]?.label?.rotation"
|
[rotation]="link.nodes[0].label.rotation"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<svg:g
|
<svg:g
|
||||||
*ngIf="showInterfaceLabels"
|
*ngIf="showInterfaceLabels"
|
||||||
[app-interface-label]
|
[app-interface-label]
|
||||||
[x]="link?.target?.x + link?.nodes[1]?.label?.x"
|
[x]="link.target.x + link.nodes[1].label.x"
|
||||||
[y]="link?.target?.y + link?.nodes[1]?.label?.y"
|
[y]="link.target.y + link.nodes[1].label.y"
|
||||||
[text]="link?.nodes[1]?.label?.text"
|
[text]="link.nodes[1].label.text"
|
||||||
[style]="link?.nodes[1]?.label?.style"
|
[style]="link.nodes[1].label.style"
|
||||||
[rotation]="link?.nodes[1]?.label?.rotation"
|
[rotation]="link.nodes[1].label.rotation"
|
||||||
/>
|
/>
|
||||||
</svg:g>
|
</svg:g>
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
@ -1,18 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { MultiLinkCalculatorHelper } from 'app/cartography/helpers/multi-link-calculator-helper';
|
|
||||||
import { LinkComponent } from './link.component';
|
import { LinkComponent } from './link.component';
|
||||||
|
|
||||||
describe('LinkComponent', () => {
|
describe('LinkComponent', () => {
|
||||||
let component: LinkComponent;
|
let component: LinkComponent;
|
||||||
let fixture: ComponentFixture<LinkComponent>;
|
let fixture: ComponentFixture<LinkComponent>;
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
declarations: [LinkComponent],
|
declarations: [LinkComponent],
|
||||||
providers: [
|
|
||||||
{ provide: MultiLinkCalculatorHelper, useValue: {} }
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(LinkComponent);
|
fixture = TestBed.createComponent(LinkComponent);
|
||||||
@ -20,7 +17,7 @@ describe('LinkComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -33,7 +33,7 @@ export class LinkComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
private nodeChangedSubscription: Subscription;
|
private nodeChangedSubscription: Subscription;
|
||||||
|
|
||||||
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private ref: ChangeDetectorRef) { }
|
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private ref: ChangeDetectorRef) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.ref.detectChanges();
|
this.ref.detectChanges();
|
||||||
@ -49,21 +49,19 @@ export class LinkComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get strategy(): LinkStrategy {
|
get strategy(): LinkStrategy {
|
||||||
if (this.link && this.link != undefined && this.link.linkType === 'serial') {
|
if (this.link.linkType === 'serial') {
|
||||||
return this.serialLinkStrategy;
|
return this.serialLinkStrategy;
|
||||||
}
|
}
|
||||||
return this.ethernetLinkStrategy;
|
return this.ethernetLinkStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
get transform() {
|
get transform() {
|
||||||
if (this.link) {
|
const translation = this.multiLinkCalculatorHelper.linkTranslation(
|
||||||
const translation = this.multiLinkCalculatorHelper.linkTranslation(
|
this.link.distance,
|
||||||
this.link.distance,
|
this.link.source,
|
||||||
this.link.source,
|
this.link.target
|
||||||
this.link.target
|
);
|
||||||
);
|
return `translate (${translation.dx}, ${translation.dy})`;
|
||||||
return `translate (${translation.dx}, ${translation.dy})`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get d() {
|
get d() {
|
||||||
|
@ -5,9 +5,8 @@ import { LinkStrategy } from './link-strategy';
|
|||||||
export class EthernetLinkStrategy implements LinkStrategy {
|
export class EthernetLinkStrategy implements LinkStrategy {
|
||||||
public d(link: MapLink): string {
|
public d(link: MapLink): string {
|
||||||
const points = [
|
const points = [
|
||||||
|
[link.source.x + link.source.width / 2, link.source.y + link.source.height / 2],
|
||||||
[link?.source?.x + link?.source?.width / 2, link?.source.y + link?.source?.height / 2],
|
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2],
|
||||||
[link?.target?.x + link?.target?.width / 2, link?.target?.y + link?.target?.height / 2],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const line_generator = path();
|
const line_generator = path();
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<svg:g class="node" [attr.transform]="'translate(' + node?.x + ',' + node?.y + ')'">
|
<svg:g class="node" [attr.transform]="'translate(' + node.x + ',' + node.y + ')'">
|
||||||
<svg:image
|
<svg:image
|
||||||
#image
|
#image
|
||||||
[attr.width]="node?.width"
|
[attr.width]="node.width"
|
||||||
[attr.height]="node?.height"
|
[attr.height]="node.height"
|
||||||
[attr.x]="0"
|
[attr.x]="0"
|
||||||
[attr.y]="0"
|
[attr.y]="0"
|
||||||
[attr.xlink:href]="symbol"
|
[attr.xlink:href]="symbol"
|
||||||
@ -11,6 +11,6 @@
|
|||||||
(dragged)="OnDragged($event)"
|
(dragged)="OnDragged($event)"
|
||||||
/>
|
/>
|
||||||
<svg:text #label class="label" [attr.style]="label_style" [attr.x]="label_x" [attr.y]="label_y">
|
<svg:text #label class="label" [attr.style]="label_style" [attr.x]="label_x" [attr.y]="label_y">
|
||||||
{{ node?.label?.text }}
|
{{ node.label.text }}
|
||||||
</svg:text>
|
</svg:text>
|
||||||
</svg:g>
|
</svg:g>
|
||||||
|
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 484 B |
@ -1,23 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { NodesEventSource } from 'app/cartography/events/nodes-event-source';
|
|
||||||
import { CssFixer } from 'app/cartography/helpers/css-fixer';
|
|
||||||
import { FontFixer } from 'app/cartography/helpers/font-fixer';
|
|
||||||
import { NodeComponent } from './node.component';
|
import { NodeComponent } from './node.component';
|
||||||
|
|
||||||
describe('NodeComponent', () => {
|
describe('NodeComponent', () => {
|
||||||
let component: NodeComponent;
|
let component: NodeComponent;
|
||||||
let fixture: ComponentFixture<NodeComponent>;
|
let fixture: ComponentFixture<NodeComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [NodeComponent],
|
declarations: [NodeComponent],
|
||||||
providers:[
|
|
||||||
CssFixer,
|
|
||||||
FontFixer,
|
|
||||||
NodesEventSource,
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(NodeComponent);
|
fixture = TestBed.createComponent(NodeComponent);
|
||||||
@ -25,7 +17,7 @@ describe('NodeComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -49,7 +49,7 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
|||||||
protected element: ElementRef,
|
protected element: ElementRef,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
private nodesEventSource: NodesEventSource
|
private nodesEventSource: NodesEventSource
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
// this.nodeChangedSubscription = this.nodeChanged.subscribe((node: Node) => {
|
// this.nodeChangedSubscription = this.nodeChanged.subscribe((node: Node) => {
|
||||||
@ -85,52 +85,42 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
get symbol(): string {
|
get symbol(): string {
|
||||||
if (this.symbols) {
|
const symbol = this.symbols.find((s: Symbol) => s.symbol_id === this.node.symbol);
|
||||||
const symbol = this.symbols.find((s: Symbol) => s.symbol_id === this.node.symbol);
|
if (symbol) {
|
||||||
if (symbol) {
|
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
|
||||||
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
|
|
||||||
}
|
|
||||||
// @todo; we need to have default image
|
|
||||||
return 'data:image/svg+xml;base64,none';
|
|
||||||
}
|
}
|
||||||
|
// @todo; we need to have default image
|
||||||
|
return 'data:image/svg+xml;base64,none';
|
||||||
}
|
}
|
||||||
|
|
||||||
get label_style() {
|
get label_style() {
|
||||||
if (this.node != undefined) {
|
let styles = this.cssFixer.fix(this.node.label.style);
|
||||||
let styles = this.cssFixer.fix(this.node.label.style);
|
styles = this.fontFixer.fixStyles(styles);
|
||||||
styles = this.fontFixer.fixStyles(styles);
|
return this.sanitizer.bypassSecurityTrustStyle(styles);
|
||||||
return this.sanitizer.bypassSecurityTrustStyle(styles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get label_x(): number {
|
get label_x(): number {
|
||||||
if (this.node != undefined) {
|
if (this.node.label.x === null) {
|
||||||
if (this.node.label.x === null) {
|
// center
|
||||||
// center
|
const bbox = this.label.nativeElement.getBBox();
|
||||||
const bbox = this.label.nativeElement.getBBox();
|
|
||||||
|
|
||||||
return -bbox.width / 2;
|
return -bbox.width / 2;
|
||||||
}
|
|
||||||
return this.node.label.x + NodeComponent.NODE_LABEL_MARGIN;
|
|
||||||
}
|
}
|
||||||
|
return this.node.label.x + NodeComponent.NODE_LABEL_MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
get label_y(): number {
|
get label_y(): number {
|
||||||
this.labelHeight = this.getLabelHeight();
|
this.labelHeight = this.getLabelHeight();
|
||||||
|
|
||||||
if (this.node != undefined) {
|
if (this.node.label.x === null) {
|
||||||
if (this.node.label.x === null) {
|
// center
|
||||||
// center
|
return -this.node.height / 2 - this.labelHeight;
|
||||||
return -this.node.height / 2 - this.labelHeight;
|
|
||||||
}
|
|
||||||
return this.node.label.y + this.labelHeight - NodeComponent.NODE_LABEL_MARGIN;
|
|
||||||
}
|
}
|
||||||
|
return this.node.label.y + this.labelHeight - NodeComponent.NODE_LABEL_MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLabelHeight() {
|
private getLabelHeight() {
|
||||||
if (this.label != undefined) {
|
const bbox = this.label.nativeElement.getBBox();
|
||||||
const bbox = this.label.nativeElement.getBBox();
|
return bbox.height;
|
||||||
return bbox.height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { SelectionComponent } from './selection.component';
|
import { SelectionComponent } from './selection.component';
|
||||||
|
|
||||||
describe('SelectionComponent', () => {
|
describe('SelectionComponent', () => {
|
||||||
let component: SelectionComponent;
|
let component: SelectionComponent;
|
||||||
let fixture: ComponentFixture<SelectionComponent>;
|
let fixture: ComponentFixture<SelectionComponent>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [SelectionComponent],
|
declarations: [SelectionComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(SelectionComponent);
|
fixture = TestBed.createComponent(SelectionComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
|
||||||
fixture.destroy()
|
|
||||||
})
|
|
||||||
|
|
||||||
|
// it('should create', () => {
|
||||||
it('should create', () => {
|
// expect(component).toBeTruthy();
|
||||||
expect(component).toBeTruthy();
|
// });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { Observable, Subscription} from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
import { Rectangle } from '../../../models/rectangle';
|
import { Rectangle } from '../../../models/rectangle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -28,14 +28,15 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
const down = Observable.fromEvent(this.svg, 'mousedown').do((e: MouseEvent) => e.preventDefault());
|
const down = Observable.fromEvent(this.svg, 'mousedown').do((e: MouseEvent) => e.preventDefault());
|
||||||
|
|
||||||
down.subscribe((e: MouseEvent) => {
|
down.subscribe((e: MouseEvent) => {
|
||||||
if (e.target !== this.svg) {
|
if (e.target !== this.svg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.started = true;
|
this.started = true;
|
||||||
this.startX = e?.clientX + window?.scrollX;
|
this.startX = e.clientX + window.scrollX;
|
||||||
this.startY = e?.clientY + window?.scrollY;
|
this.startY = e.clientY + window.scrollY;
|
||||||
this.width = 0;
|
this.width = 0;
|
||||||
this.height = 0;
|
this.height = 0;
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
@ -50,7 +51,7 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
const scrollWindow = Observable.fromEvent(document, 'scroll').startWith({});
|
const scrollWindow = Observable.fromEvent(document, 'scroll').startWith({});
|
||||||
|
|
||||||
const move = Observable.combineLatest([mouseMove, scrollWindow]);
|
const move = Observable.combineLatest(mouseMove, scrollWindow);
|
||||||
|
|
||||||
const drag = down.mergeMap((md: MouseEvent) => {
|
const drag = down.mergeMap((md: MouseEvent) => {
|
||||||
return move
|
return move
|
||||||
@ -75,11 +76,11 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
|||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.started = false;
|
this.started = false;
|
||||||
|
|
||||||
|
|
||||||
this.width = e.clientX - this.startX + window.scrollX;
|
this.width = e.clientX - this.startX + window.scrollX;
|
||||||
this.height = e.clientY - this.startY + window.scrollY;
|
this.height = e.clientY - this.startY + window.scrollY;
|
||||||
|
|
||||||
this.ref.detectChanges();
|
this.ref.detectChanges();
|
||||||
|
|
||||||
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { StatusComponent } from './status.component';
|
import { StatusComponent } from './status.component';
|
||||||
|
|
||||||
describe('StatusComponent', () => {
|
describe('StatusComponent', () => {
|
||||||
let component: StatusComponent;
|
let component: StatusComponent;
|
||||||
let fixture: ComponentFixture<StatusComponent>;
|
let fixture: ComponentFixture<StatusComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [StatusComponent],
|
declarations: [StatusComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(StatusComponent);
|
fixture = TestBed.createComponent(StatusComponent);
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
|
||||||
import { select } from 'd3-selection';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
import { LinksEventSource } from '../../events/links-event-source';
|
|
||||||
import { MapLink } from '../../models/map/map-link';
|
|
||||||
import { LinksWidget } from '../../widgets/links';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-link-editing',
|
|
||||||
templateUrl: './link-editing.component.html',
|
|
||||||
styleUrls: ['./link-editing.component.scss'],
|
|
||||||
})
|
|
||||||
export class LinkEditingComponent implements OnInit, OnDestroy {
|
|
||||||
private linkEditedSubscription: Subscription;
|
|
||||||
@Input('svg') svg: SVGSVGElement;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private linksWidget: LinksWidget,
|
|
||||||
private linksEventSource: LinksEventSource ) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
const svg = select(this.svg);
|
|
||||||
this.linkEditedSubscription = this.linksEventSource.edited.subscribe((link: MapLink) => {
|
|
||||||
this.linksWidget.redrawLink(svg, link);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.linkEditedSubscription.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { SelectionManager } from 'app/cartography/managers/selection-manager';
|
|
||||||
import { MapChangeDetectorRef } from 'app/cartography/services/map-change-detector-ref';
|
|
||||||
import { SelectionSelectComponent } from './selection-select.component';
|
import { SelectionSelectComponent } from './selection-select.component';
|
||||||
|
|
||||||
describe('SelectionSelectComponent', () => {
|
describe('SelectionSelectComponent', () => {
|
||||||
let component: SelectionSelectComponent;
|
let component: SelectionSelectComponent;
|
||||||
let fixture: ComponentFixture<SelectionSelectComponent>;
|
let fixture: ComponentFixture<SelectionSelectComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [SelectionSelectComponent],
|
declarations: [SelectionSelectComponent],
|
||||||
providers: [MapChangeDetectorRef,SelectionManager]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(SelectionSelectComponent);
|
fixture = TestBed.createComponent(SelectionSelectComponent);
|
||||||
@ -20,7 +17,7 @@ describe('SelectionSelectComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Renderer2 } from '@angular/core';
|
import { Renderer2 } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { MockedLinkService } from '../../../components/project-map/project-map.component.spec';
|
import { MockedLinkService } from '../../../components/project-map/project-map.component.spec';
|
||||||
import { LinkService } from '../../../services/link.service';
|
import { LinkService } from '../../../services/link.service';
|
||||||
@ -18,7 +18,7 @@ describe('TextEditorComponent', () => {
|
|||||||
let fixture: ComponentFixture<TextEditorComponent>;
|
let fixture: ComponentFixture<TextEditorComponent>;
|
||||||
let mockedLinkService: MockedLinkService = new MockedLinkService();
|
let mockedLinkService: MockedLinkService = new MockedLinkService();
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
@ -35,7 +35,7 @@ describe('TextEditorComponent', () => {
|
|||||||
],
|
],
|
||||||
declarations: [TextEditorComponent],
|
declarations: [TextEditorComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(TextEditorComponent);
|
fixture = TestBed.createComponent(TextEditorComponent);
|
||||||
|
@ -13,7 +13,7 @@ import { select } from 'd3-selection';
|
|||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { StyleProperty } from '../../../components/project-map/drawings-editors/text-editor/text-editor.component';
|
import { StyleProperty } from '../../../components/project-map/drawings-editors/text-editor/text-editor.component';
|
||||||
import { Link } from '../../../models/link';
|
import { Link } from '../../../models/link';
|
||||||
import { Controller } from '../../../models/controller';
|
import { Server } from '../../../models/server';
|
||||||
import { LinkService } from '../../../services/link.service';
|
import { LinkService } from '../../../services/link.service';
|
||||||
import { MapScaleService } from '../../../services/mapScale.service';
|
import { MapScaleService } from '../../../services/mapScale.service';
|
||||||
import { ToolsService } from '../../../services/tools.service';
|
import { ToolsService } from '../../../services/tools.service';
|
||||||
@ -37,7 +37,7 @@ import { Node } from '../../models/node';
|
|||||||
export class TextEditorComponent implements OnInit, OnDestroy {
|
export class TextEditorComponent implements OnInit, OnDestroy {
|
||||||
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
||||||
@Input('svg') svg: SVGSVGElement;
|
@Input('svg') svg: SVGSVGElement;
|
||||||
@Input('controller') controller: Controller;
|
@Input('server') server: Server;
|
||||||
|
|
||||||
leftPosition: string = '0px';
|
leftPosition: string = '0px';
|
||||||
topPosition: string = '0px';
|
topPosition: string = '0px';
|
||||||
@ -185,7 +185,7 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
|||||||
let link: Link = this.linksDataSource.get(this.editedLink.linkId);
|
let link: Link = this.linksDataSource.get(this.editedLink.linkId);
|
||||||
link.nodes.find((n) => n.node_id === this.editedNode.node_id).label.text = innerText;
|
link.nodes.find((n) => n.node_id === this.editedNode.node_id).label.text = innerText;
|
||||||
|
|
||||||
this.linkService.updateLink(this.controller, link).subscribe((link: Link) => {
|
this.linkService.updateLink(this.server, link).subscribe((link: Link) => {
|
||||||
rootElement
|
rootElement
|
||||||
.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||||
.attr('visibility', 'visible')
|
.attr('visibility', 'visible')
|
||||||
|
@ -15,7 +15,6 @@ export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
|||||||
mapLink.captureFilePath = link.capture_file_path;
|
mapLink.captureFilePath = link.capture_file_path;
|
||||||
mapLink.capturing = link.capturing;
|
mapLink.capturing = link.capturing;
|
||||||
mapLink.filters = link.filters;
|
mapLink.filters = link.filters;
|
||||||
mapLink.link_style = link.link_style;
|
|
||||||
mapLink.linkType = link.link_type;
|
mapLink.linkType = link.link_type;
|
||||||
mapLink.nodes = link.nodes.map((linkNode) =>
|
mapLink.nodes = link.nodes.map((linkNode) =>
|
||||||
this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id })
|
this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id })
|
||||||
|
@ -14,11 +14,11 @@ export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
|||||||
let elem = ``;
|
let elem = ``;
|
||||||
|
|
||||||
if (mapDrawing.element instanceof RectElement) {
|
if (mapDrawing.element instanceof RectElement) {
|
||||||
elem = `${mapDrawing.element.stroke_dasharray == '' ? `<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" />` :`<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" stroke-dasharray=\"${mapDrawing.element.stroke_dasharray}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" />`}`;
|
elem = `<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" />`;
|
||||||
} else if (mapDrawing.element instanceof EllipseElement) {
|
} else if (mapDrawing.element instanceof EllipseElement) {
|
||||||
elem = `${mapDrawing.element.stroke_dasharray == '' ? `<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${mapDrawing.element.cx}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\"/>` :`<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${mapDrawing.element.cx}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" stroke-dasharray=\"${mapDrawing.element.stroke_dasharray}\" />`}`;
|
elem = `<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${mapDrawing.element.cx}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" />`;
|
||||||
} else if (mapDrawing.element instanceof LineElement) {
|
} else if (mapDrawing.element instanceof LineElement) {
|
||||||
elem = `<line stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" x1=\"${mapDrawing.element.x1}\" x2=\"${mapDrawing.element.x2}\" y1=\"${mapDrawing.element.y1}\" y2=\"${mapDrawing.element.y2}\" stroke-dasharray=\"${mapDrawing.element.stroke_dasharray ?? 'none'}\" />`;
|
elem = `<line stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" x1=\"${mapDrawing.element.x1}\" x2=\"${mapDrawing.element.x2}\" y1=\"${mapDrawing.element.y1}\" y2=\"${mapDrawing.element.y2}\" />`;
|
||||||
} else if (mapDrawing.element instanceof TextElement) {
|
} else if (mapDrawing.element instanceof TextElement) {
|
||||||
elem = `<text fill=\"${mapDrawing.element.fill}\" fill-opacity=\"1.0\" font-family=\"${mapDrawing.element.font_family}\" font-size=\"${mapDrawing.element.font_size}\" font-weight=\"${mapDrawing.element.font_weight}\">${mapDrawing.element.text}</text>`;
|
elem = `<text fill=\"${mapDrawing.element.fill}\" fill-opacity=\"1.0\" font-family=\"${mapDrawing.element.font_family}\" font-size=\"${mapDrawing.element.font_size}\" font-weight=\"${mapDrawing.element.font_weight}\">${mapDrawing.element.text}</text>`;
|
||||||
} else return '';
|
} else return '';
|
||||||
|
@ -16,7 +16,6 @@ export class MapLinkToLinkConverter implements Converter<MapLink, Link> {
|
|||||||
link.capturing = mapLink.capturing;
|
link.capturing = mapLink.capturing;
|
||||||
link.filters = mapLink.filters;
|
link.filters = mapLink.filters;
|
||||||
link.link_type = mapLink.linkType;
|
link.link_type = mapLink.linkType;
|
||||||
link.link_style = mapLink.link_style;
|
|
||||||
link.nodes = mapLink.nodes.map((mapLinkNode) => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
link.nodes = mapLink.nodes.map((mapLinkNode) => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||||
link.project_id = mapLink.projectId;
|
link.project_id = mapLink.projectId;
|
||||||
link.suspend = mapLink.suspend;
|
link.suspend = mapLink.suspend;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { MovingEventSource } from '../events/moving-event-source';
|
import { MovingEventSource } from '../events/moving-event-source';
|
||||||
import { Context } from '../models/context';
|
import { Context } from '../models/context';
|
||||||
@ -19,8 +19,8 @@ describe('MovingCanvasDirective', () => {
|
|||||||
let fixture: ComponentFixture<DummyComponent>;
|
let fixture: ComponentFixture<DummyComponent>;
|
||||||
let movingEventSource = new MovingEventSource();
|
let movingEventSource = new MovingEventSource();
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: MovingEventSource, useValue: movingEventSource },
|
{ provide: MovingEventSource, useValue: movingEventSource },
|
||||||
@ -28,7 +28,7 @@ describe('MovingCanvasDirective', () => {
|
|||||||
],
|
],
|
||||||
declarations: [DummyComponent, MovingCanvasDirective],
|
declarations: [DummyComponent, MovingCanvasDirective],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DummyComponent);
|
fixture = TestBed.createComponent(DummyComponent);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { MapScaleService } from '../../services/mapScale.service';
|
import { MapScaleService } from '../../services/mapScale.service';
|
||||||
import { MovingEventSource } from '../events/moving-event-source';
|
import { MovingEventSource } from '../events/moving-event-source';
|
||||||
@ -20,8 +20,8 @@ describe('ZoomingCanvasDirective', () => {
|
|||||||
let fixture: ComponentFixture<DummyComponent>;
|
let fixture: ComponentFixture<DummyComponent>;
|
||||||
let movingEventSource = new MovingEventSource();
|
let movingEventSource = new MovingEventSource();
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: MovingEventSource, useValue: movingEventSource },
|
{ provide: MovingEventSource, useValue: movingEventSource },
|
||||||
@ -30,7 +30,7 @@ describe('ZoomingCanvasDirective', () => {
|
|||||||
],
|
],
|
||||||
declarations: [DummyComponent, ZoomingCanvasDirective],
|
declarations: [DummyComponent, ZoomingCanvasDirective],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DummyComponent);
|
fixture = TestBed.createComponent(DummyComponent);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { EventEmitter, Injectable } from '@angular/core';
|
import { EventEmitter, Injectable } from '@angular/core';
|
||||||
import { MapLink } from '../models/map/map-link';
|
|
||||||
import { MapLinkNode } from '../models/map/map-link-node';
|
import { MapLinkNode } from '../models/map/map-link-node';
|
||||||
import { DraggedDataEvent } from './event-source';
|
import { DraggedDataEvent } from './event-source';
|
||||||
import { MapLinkCreated } from './links';
|
import { MapLinkCreated } from './links';
|
||||||
@ -7,6 +6,5 @@ import { MapLinkCreated } from './links';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class LinksEventSource {
|
export class LinksEventSource {
|
||||||
public created = new EventEmitter<MapLinkCreated>();
|
public created = new EventEmitter<MapLinkCreated>();
|
||||||
public edited = new EventEmitter<MapLink>();
|
|
||||||
public interfaceDragged = new EventEmitter<DraggedDataEvent<MapLinkNode>>();
|
public interfaceDragged = new EventEmitter<DraggedDataEvent<MapLinkNode>>();
|
||||||
}
|
}
|
||||||
|
@ -8,47 +8,43 @@ describe('FontFixer', () => {
|
|||||||
fixer = new FontFixer();
|
fixer = new FontFixer();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fix TypeWriter font and 10px size", () => {
|
it('should fix TypeWriter font and 10px size', () => {
|
||||||
const font: Font = {
|
const font: Font = {
|
||||||
font_family: "TypeWriter",
|
font_family: 'TypeWriter',
|
||||||
font_size: 10,
|
font_size: 10,
|
||||||
font_weight: "bold",
|
font_weight: 'bold',
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(fixer.fix(font)).toEqual({
|
expect(fixer.fix(font)).toEqual({
|
||||||
font_family: "Noto Sans",
|
font_family: 'Arial',
|
||||||
font_size: 11,
|
font_size: 12,
|
||||||
font_weight: "bold",
|
font_weight: 'bold',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not fix other fonts", () => {
|
it('should not fix other fonts', () => {
|
||||||
const font: Font = {
|
const font: Font = {
|
||||||
font_family: "OtherFont",
|
font_family: 'OtherFont',
|
||||||
font_size: 11,
|
font_size: 11,
|
||||||
font_weight: "bold",
|
font_weight: 'bold',
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(fixer.fix(font)).toEqual({
|
expect(fixer.fix(font)).toEqual({
|
||||||
font_family: "OtherFont",
|
font_family: 'OtherFont',
|
||||||
font_size: 11,
|
font_size: 11,
|
||||||
font_weight: "bold",
|
font_weight: 'bold',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fix TypeWriter font and 10px size in styles', () => {
|
it('should fix TypeWriter font and 10px size in styles', () => {
|
||||||
let typeWriter = "TypeWriter";
|
const styles = 'font-family: TypeWriter; font-size: 10px; font-weight: bold';
|
||||||
let notoSans = "Noto Sans";
|
|
||||||
const styles = `font-family:${typeWriter} ; font-size: 10px; font-weight: bold`;
|
|
||||||
|
|
||||||
expect(fixer.fixStyles(styles)).toEqual(`font-family:${notoSans};font-size:11px;font-weight:bold`);
|
expect(fixer.fixStyles(styles)).toEqual('font-family:Arial;font-size:12px;font-weight:bold');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fix TypeWriter font and 10px size in styles with quotes", () => {
|
it('should fix TypeWriter font and 10px size in styles with quotes', () => {
|
||||||
let typeWriter = "TypeWriter";
|
const styles = 'font-family: "TypeWriter"; font-size: 10px; font-weight: bold';
|
||||||
let notoSans = "Noto Sans";
|
|
||||||
const styles = `font-family:${typeWriter}; font-size: 10px; font-weight: bold`;
|
|
||||||
|
|
||||||
expect(fixer.fixStyles(styles)).toEqual(`font-family:${notoSans};font-size:11px;font-weight:bold`);
|
expect(fixer.fixStyles(styles)).toEqual('font-family:Arial;font-size:12px;font-weight:bold');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,8 +9,8 @@ import { Font } from '../models/font';
|
|||||||
export class FontFixer {
|
export class FontFixer {
|
||||||
static DEFAULT_FONT = 'TypeWriter';
|
static DEFAULT_FONT = 'TypeWriter';
|
||||||
static DEFAULT_SIZE = 10;
|
static DEFAULT_SIZE = 10;
|
||||||
static REPLACE_BY_FONT = 'Noto Sans';
|
static REPLACE_BY_FONT = 'Arial';
|
||||||
static REPLACE_BY_SIZE = 11;
|
static REPLACE_BY_SIZE = 12;
|
||||||
|
|
||||||
public fix(font: Font): Font {
|
public fix(font: Font): Font {
|
||||||
if (font.font_family === FontFixer.DEFAULT_FONT && font.font_size === FontFixer.DEFAULT_SIZE) {
|
if (font.font_family === FontFixer.DEFAULT_FONT && font.font_size === FontFixer.DEFAULT_SIZE) {
|
||||||
|
@ -7,18 +7,16 @@ import { Injectable } from '@angular/core';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class QtDasharrayFixer {
|
export class QtDasharrayFixer {
|
||||||
static MAPPING = {
|
static MAPPING = {
|
||||||
'25, 25': '10, 2', // Dash
|
'25, 25': '10, 2',
|
||||||
'5, 25': '4, 2', // Dot
|
'5, 25': '4, 2',
|
||||||
'5, 25, 25': '12, 3, 5, 3', // Dash Dot
|
'5, 25, 25': '5, 5, 1, 5',
|
||||||
'25, 25, 5, 25, 5': '12, 3, 5, 3, 5, 3', // Dash Dot Dot
|
'25, 25, 5, 25, 5': '5, 2, 5, 2, 5',
|
||||||
};
|
};
|
||||||
|
|
||||||
public fix(dasharray: string): string {
|
public fix(dasharray: string): string {
|
||||||
if(dasharray || dasharray == '' ){
|
|
||||||
if (dasharray in QtDasharrayFixer.MAPPING) {
|
if (dasharray in QtDasharrayFixer.MAPPING) {
|
||||||
return QtDasharrayFixer.MAPPING[dasharray];
|
return QtDasharrayFixer.MAPPING[dasharray];
|
||||||
}
|
}
|
||||||
return dasharray;
|
return dasharray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -45,7 +45,6 @@ export class GraphDataManager {
|
|||||||
|
|
||||||
public setLinks(links: Link[]) {
|
public setLinks(links: Link[]) {
|
||||||
if (links) {
|
if (links) {
|
||||||
console.log("from set links");
|
|
||||||
const mapLinks = links.map((l) => this.linkToMapLink.convert(l));
|
const mapLinks = links.map((l) => this.linkToMapLink.convert(l));
|
||||||
this.mapLinksDataSource.set(mapLinks);
|
this.mapLinksDataSource.set(mapLinks);
|
||||||
|
|
||||||
@ -89,7 +88,6 @@ export class GraphDataManager {
|
|||||||
private onDataUpdate() {
|
private onDataUpdate() {
|
||||||
this.layersManager.clear();
|
this.layersManager.clear();
|
||||||
this.layersManager.setNodes(this.getNodes());
|
this.layersManager.setNodes(this.getNodes());
|
||||||
console.log(this.getLinks());
|
|
||||||
this.layersManager.setLinks(this.getLinks());
|
this.layersManager.setLinks(this.getLinks());
|
||||||
this.layersManager.setDrawings(this.getDrawings());
|
this.layersManager.setDrawings(this.getDrawings());
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ export class LayersManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setLinks(links: MapLink[]) {
|
public setLinks(links: MapLink[]) {
|
||||||
console.log('from set links 2');
|
|
||||||
links
|
links
|
||||||
.filter((link: MapLink) => link.source && link.target)
|
.filter((link: MapLink) => link.source && link.target)
|
||||||
.forEach((link: MapLink) => {
|
.forEach((link: MapLink) => {
|
||||||
|
@ -2,7 +2,6 @@ import { Filter } from '../../../models/filter';
|
|||||||
import { Indexed } from '../../datasources/map-datasource';
|
import { Indexed } from '../../datasources/map-datasource';
|
||||||
import { MapLinkNode } from './map-link-node';
|
import { MapLinkNode } from './map-link-node';
|
||||||
import { MapNode } from './map-node';
|
import { MapNode } from './map-node';
|
||||||
import { LinkStyle } from '../../../models/link-style';
|
|
||||||
|
|
||||||
export class MapLink implements Indexed {
|
export class MapLink implements Indexed {
|
||||||
id: string;
|
id: string;
|
||||||
@ -14,15 +13,14 @@ export class MapLink implements Indexed {
|
|||||||
nodes: MapLinkNode[];
|
nodes: MapLinkNode[];
|
||||||
projectId: string;
|
projectId: string;
|
||||||
suspend: boolean;
|
suspend: boolean;
|
||||||
link_style?: LinkStyle;
|
|
||||||
|
|
||||||
distance: number; // this is not from controller
|
distance: number; // this is not from server
|
||||||
length: number; // this is not from controller
|
length: number; // this is not from server
|
||||||
source: MapNode; // this is not from controller
|
source: MapNode; // this is not from server
|
||||||
target: MapNode; // this is not from controller
|
target: MapNode; // this is not from server
|
||||||
|
|
||||||
isSelected = false; // this is not from controller
|
isSelected = false; // this is not from server
|
||||||
isMultiplied = false; // this is not from controller
|
isMultiplied = false; // this is not from server
|
||||||
x: number; // this is not from controller
|
x: number; // this is not from server
|
||||||
y: number; // this is not from controller
|
y: number; // this is not from server
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ export class Properties {
|
|||||||
headless: boolean;
|
headless: boolean;
|
||||||
linked_clone: boolean;
|
linked_clone: boolean;
|
||||||
on_close: string;
|
on_close: string;
|
||||||
|
aux: number;
|
||||||
ram: number;
|
ram: number;
|
||||||
nvram: number;
|
nvram: number;
|
||||||
usage: string;
|
usage: string;
|
||||||
@ -45,6 +46,7 @@ export class Properties {
|
|||||||
kernel_command_line: string;
|
kernel_command_line: string;
|
||||||
kernel_image: string;
|
kernel_image: string;
|
||||||
kernel_image_md5sum?: any;
|
kernel_image_md5sum?: any;
|
||||||
|
legacy_networking: boolean;
|
||||||
mac_address: string;
|
mac_address: string;
|
||||||
options: string;
|
options: string;
|
||||||
platform: string;
|
platform: string;
|
||||||
@ -52,8 +54,8 @@ export class Properties {
|
|||||||
qemu_path: string;
|
qemu_path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
extra_hosts: string;
|
extra_hosts: string;
|
||||||
|
extra_volumes: string[];
|
||||||
replicate_network_connection_state: boolean;
|
replicate_network_connection_state: boolean;
|
||||||
memory: number;
|
|
||||||
tpm: boolean;
|
tpm: boolean;
|
||||||
uefi: boolean;
|
uefi: boolean;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ export class MapChangeDetectorRef {
|
|||||||
public hasBeenDrawn = false;
|
public hasBeenDrawn = false;
|
||||||
|
|
||||||
public detectChanges() {
|
public detectChanges() {
|
||||||
console.log('from map change detector');
|
|
||||||
this.changesDetected.emit(true);
|
this.changesDetected.emit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ describe('TextDrawingWidget', () => {
|
|||||||
const text_element = drew.nodes()[0];
|
const text_element = drew.nodes()[0];
|
||||||
expect(text_element.innerHTML).toEqual('<tspan xml:space="preserve" x="0" dy="0em">THIS IS TEXT</tspan>');
|
expect(text_element.innerHTML).toEqual('<tspan xml:space="preserve" x="0" dy="0em">THIS IS TEXT</tspan>');
|
||||||
expect(text_element.getAttribute('fill')).toEqual('#000000');
|
expect(text_element.getAttribute('fill')).toEqual('#000000');
|
||||||
expect(text_element.getAttribute('style')).toEqual('font-family: "Noto Sans"; font-size: 11pt; font-weight: bold');
|
expect(text_element.getAttribute('style')).toEqual('font-family: "Arial"; font-size: 12pt; font-weight: bold');
|
||||||
expect(text_element.getAttribute('text-decoration')).toEqual('line-through');
|
expect(text_element.getAttribute('text-decoration')).toEqual('line-through');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -52,13 +52,13 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
new LinkStatus(
|
new LinkStatus(
|
||||||
start_point.x,
|
start_point.x,
|
||||||
start_point.y,
|
start_point.y,
|
||||||
(( !l.capturing && l.suspend) || ( l.capturing && l.suspend)) ? 'suspended' : l.source.status,
|
l.capturing && l.suspend ? 'suspended' : l.source.status,
|
||||||
sourcePort
|
sourcePort
|
||||||
),
|
),
|
||||||
new LinkStatus(
|
new LinkStatus(
|
||||||
end_point.x,
|
end_point.x,
|
||||||
end_point.y,
|
end_point.y,
|
||||||
(( !l.capturing && l.suspend) || ( l.capturing && l.suspend)) ? 'suspended' : l.target.status,
|
l.capturing && l.suspend ? 'suspended' : l.target.status,
|
||||||
destinationPort
|
destinationPort
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@ -90,16 +90,16 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.merge(status_started_enter)
|
.merge(status_started_enter)
|
||||||
.attr('class', 'status_started')
|
.attr('class', 'status_started')
|
||||||
.attr('width', (ls: LinkStatus) => {
|
.attr('width', (ls: LinkStatus) => {
|
||||||
return ls.port.length * 8 + 10;
|
return ls.port.length * 10 + 5;
|
||||||
})
|
})
|
||||||
.attr('height', 20)
|
.attr('height', 20)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 30)
|
.attr('x', (ls: LinkStatus) => ls.x - 30)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
.attr('rx', 8)
|
.attr('rx', 8)
|
||||||
.attr('ry', 8)
|
.attr('ry', 8)
|
||||||
.style('fill', 'white')
|
.style('fill', '#c7ffdf')
|
||||||
.attr('stroke', '#2ecc71')
|
.attr('stroke', '#2ecc71')
|
||||||
.attr('stroke-width', 3);
|
.attr('stroke-width', 2);
|
||||||
status_started.exit().remove();
|
status_started.exit().remove();
|
||||||
const status_started_label = link_group
|
const status_started_label = link_group
|
||||||
.selectAll<SVGTextElement, LinkStatus>('text.status_started_label')
|
.selectAll<SVGTextElement, LinkStatus>('text.status_started_label')
|
||||||
@ -111,7 +111,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.text((ls: LinkStatus) => ls.port)
|
.text((ls: LinkStatus) => ls.port)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
.attr('fill', `black`);
|
.attr('fill', `#0e9647`);
|
||||||
status_started_label.exit().remove();
|
status_started_label.exit().remove();
|
||||||
|
|
||||||
const status_stopped = link_group
|
const status_stopped = link_group
|
||||||
@ -122,16 +122,16 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.merge(status_stopped_enter)
|
.merge(status_stopped_enter)
|
||||||
.attr('class', 'status_stopped')
|
.attr('class', 'status_stopped')
|
||||||
.attr('width', (ls: LinkStatus) => {
|
.attr('width', (ls: LinkStatus) => {
|
||||||
return ls.port.length * 8 + 10;
|
return ls.port.length * 10 + 5;
|
||||||
})
|
})
|
||||||
.attr('height', 20)
|
.attr('height', 20)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 30)
|
.attr('x', (ls: LinkStatus) => ls.x - 30)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
.attr('rx', 8)
|
.attr('rx', 8)
|
||||||
.attr('ry', 8)
|
.attr('ry', 8)
|
||||||
.style('fill', 'white')
|
.style('fill', '#ffe3e3')
|
||||||
.attr('stroke', 'red')
|
.attr('stroke', 'red')
|
||||||
.attr('stroke-width', 3);
|
.attr('stroke-width', 2);
|
||||||
status_stopped.exit().remove();
|
status_stopped.exit().remove();
|
||||||
const status_stopped_label = link_group
|
const status_stopped_label = link_group
|
||||||
.selectAll<SVGTextElement, LinkStatus>('text.status_stopped_label')
|
.selectAll<SVGTextElement, LinkStatus>('text.status_stopped_label')
|
||||||
@ -143,7 +143,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.text((ls: LinkStatus) => ls.port)
|
.text((ls: LinkStatus) => ls.port)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
.attr('fill', `black`);
|
.attr('fill', `red`);
|
||||||
status_stopped_label.exit().remove();
|
status_stopped_label.exit().remove();
|
||||||
|
|
||||||
const status_suspended = link_group
|
const status_suspended = link_group
|
||||||
@ -154,7 +154,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.merge(status_suspended_enter)
|
.merge(status_suspended_enter)
|
||||||
.attr('class', 'status_suspended')
|
.attr('class', 'status_suspended')
|
||||||
.attr('width', (ls: LinkStatus) => {
|
.attr('width', (ls: LinkStatus) => {
|
||||||
return ls.port.length * 8 + 10;
|
return ls.port.length * 10 + 5;
|
||||||
})
|
})
|
||||||
.attr('height', 20)
|
.attr('height', 20)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 30)
|
.attr('x', (ls: LinkStatus) => ls.x - 30)
|
||||||
@ -162,8 +162,8 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.attr('rx', 8)
|
.attr('rx', 8)
|
||||||
.attr('ry', 8)
|
.attr('ry', 8)
|
||||||
.style('fill', 'white')
|
.style('fill', 'white')
|
||||||
.attr('stroke', '#FFFF00')
|
.attr('stroke', '#fffbc3')
|
||||||
.attr('stroke-width', 3);
|
.attr('stroke-width', 2);
|
||||||
status_suspended.exit().remove();
|
status_suspended.exit().remove();
|
||||||
const status_suspended_label = link_group
|
const status_suspended_label = link_group
|
||||||
.selectAll<SVGTextElement, LinkStatus>('text.status_suspended_label')
|
.selectAll<SVGTextElement, LinkStatus>('text.status_suspended_label')
|
||||||
@ -175,7 +175,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.text((ls: LinkStatus) => ls.port)
|
.text((ls: LinkStatus) => ls.port)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
.attr('fill', `black`);
|
.attr('fill', `#6b5633`);
|
||||||
status_suspended_label.exit().remove();
|
status_suspended_label.exit().remove();
|
||||||
} else {
|
} else {
|
||||||
const status_started = link_group
|
const status_started = link_group
|
||||||
|
@ -22,15 +22,14 @@ export class LinkWidget implements Widget {
|
|||||||
private selectionManager: SelectionManager,
|
private selectionManager: SelectionManager,
|
||||||
private ethernetLinkWidget: EthernetLinkWidget,
|
private ethernetLinkWidget: EthernetLinkWidget,
|
||||||
private serialLinkWidget: SerialLinkWidget
|
private serialLinkWidget: SerialLinkWidget
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const link_body = view.selectAll<SVGGElement, MapLink>('g.link_body').data((l) => [l]);
|
const link_body = view.selectAll<SVGGElement, MapLink>('g.link_body').data((l) => [l]);
|
||||||
|
|
||||||
const link_body_enter = link_body.enter().append<SVGGElement>('g').attr('class', 'link_body');
|
const link_body_enter = link_body.enter().append<SVGGElement>('g').attr('class', 'link_body');
|
||||||
|
|
||||||
const link_body_merge = link_body.merge(link_body_enter)
|
const link_body_merge = link_body.merge(link_body_enter).attr('transform', (link) => {
|
||||||
.attr('transform', (link) => {
|
|
||||||
const translation = this.multiLinkCalculatorHelper.linkTranslation(link.distance, link.source, link.target);
|
const translation = this.multiLinkCalculatorHelper.linkTranslation(link.distance, link.source, link.target);
|
||||||
return `translate (${translation.dx}, ${translation.dy})`;
|
return `translate (${translation.dx}, ${translation.dy})`;
|
||||||
});
|
});
|
||||||
@ -51,8 +50,9 @@ export class LinkWidget implements Widget {
|
|||||||
})
|
})
|
||||||
.attr('class', 'capture-icon')
|
.attr('class', 'capture-icon')
|
||||||
.attr('transform', (link) => {
|
.attr('transform', (link) => {
|
||||||
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${(link.source.y + link.target.y) / 2 + 24
|
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${
|
||||||
}) scale(0.5)`;
|
(link.source.y + link.target.y) / 2 + 24
|
||||||
|
}) scale(0.5)`;
|
||||||
})
|
})
|
||||||
.attr('viewBox', '0 0 20 20')
|
.attr('viewBox', '0 0 20 20')
|
||||||
.append<SVGImageElement>('image')
|
.append<SVGImageElement>('image')
|
||||||
@ -74,8 +74,9 @@ export class LinkWidget implements Widget {
|
|||||||
})
|
})
|
||||||
.attr('class', 'filter-capture-icon')
|
.attr('class', 'filter-capture-icon')
|
||||||
.attr('transform', (link) => {
|
.attr('transform', (link) => {
|
||||||
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${(link.source.y + link.target.y) / 2 + 24
|
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${
|
||||||
}) scale(0.5)`;
|
(link.source.y + link.target.y) / 2 + 24
|
||||||
|
}) scale(0.5)`;
|
||||||
})
|
})
|
||||||
.attr('viewBox', '0 0 20 20')
|
.attr('viewBox', '0 0 20 20')
|
||||||
.append<SVGImageElement>('image')
|
.append<SVGImageElement>('image')
|
||||||
@ -99,8 +100,9 @@ export class LinkWidget implements Widget {
|
|||||||
.attr('width', '48px')
|
.attr('width', '48px')
|
||||||
.attr('height', '48px')
|
.attr('height', '48px')
|
||||||
.attr('transform', (link) => {
|
.attr('transform', (link) => {
|
||||||
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${(link.source.y + link.target.y) / 2 + 24
|
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${
|
||||||
}) scale(0.5)`;
|
(link.source.y + link.target.y) / 2 + 24
|
||||||
|
}) scale(0.5)`;
|
||||||
})
|
})
|
||||||
.attr('viewBox', '0 0 20 20')
|
.attr('viewBox', '0 0 20 20')
|
||||||
.append<SVGImageElement>('image')
|
.append<SVGImageElement>('image')
|
||||||
@ -122,8 +124,9 @@ export class LinkWidget implements Widget {
|
|||||||
})
|
})
|
||||||
.attr('class', 'pause-icon')
|
.attr('class', 'pause-icon')
|
||||||
.attr('transform', (link) => {
|
.attr('transform', (link) => {
|
||||||
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${(link.source.y + link.target.y) / 2 + 24
|
return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${
|
||||||
}) scale(0.5)`;
|
(link.source.y + link.target.y) / 2 + 24
|
||||||
|
}) scale(0.5)`;
|
||||||
})
|
})
|
||||||
.attr('viewBox', '0 0 20 20')
|
.attr('viewBox', '0 0 20 20')
|
||||||
.append<SVGImageElement>('image')
|
.append<SVGImageElement>('image')
|
||||||
|
@ -11,7 +11,6 @@ export class LinksWidget implements Widget {
|
|||||||
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private linkWidget: LinkWidget) {}
|
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private linkWidget: LinkWidget) {}
|
||||||
|
|
||||||
public redrawLink(view: SVGSelection, link: MapLink) {
|
public redrawLink(view: SVGSelection, link: MapLink) {
|
||||||
console.log('redraw called');
|
|
||||||
this.linkWidget.draw(this.selectLink(view, link));
|
this.linkWidget.draw(this.selectLink(view, link));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,29 +4,21 @@ import { LinkContextMenu } from '../../events/event-source';
|
|||||||
import { MapLink } from '../../models/map/map-link';
|
import { MapLink } from '../../models/map/map-link';
|
||||||
import { SVGSelection } from '../../models/types';
|
import { SVGSelection } from '../../models/types';
|
||||||
import { Widget } from '../widget';
|
import { Widget } from '../widget';
|
||||||
import { LinkStyle } from '../../../models/link-style';
|
|
||||||
import { StyleTranslator} from './style-translator';
|
|
||||||
|
|
||||||
class EthernetLinkPath {
|
class EthernetLinkPath {
|
||||||
constructor(public source: [number, number], public target: [number, number], public style: LinkStyle) {}
|
constructor(public source: [number, number], public target: [number, number]) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EthernetLinkWidget implements Widget {
|
export class EthernetLinkWidget implements Widget {
|
||||||
public onContextMenu = new EventEmitter<LinkContextMenu>();
|
public onContextMenu = new EventEmitter<LinkContextMenu>();
|
||||||
private defaultEthernetLinkStyle : LinkStyle = {
|
|
||||||
color: "#000",
|
|
||||||
width: 2,
|
|
||||||
type: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
private linktoEthernetLink(link: MapLink) {
|
private linktoEthernetLink(link: MapLink) {
|
||||||
return new EthernetLinkPath(
|
return new EthernetLinkPath(
|
||||||
[link.source.x + link.source.width / 2, link.source.y + link.source.height / 2],
|
[link.source.x + link.source.width / 2, link.source.y + link.source.height / 2],
|
||||||
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2],
|
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2]
|
||||||
link.link_style.color ? link.link_style : this.defaultEthernetLinkStyle
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,15 +38,15 @@ export class EthernetLinkWidget implements Widget {
|
|||||||
let link: MapLink = (datum as unknown) as MapLink;
|
let link: MapLink = (datum as unknown) as MapLink;
|
||||||
const evt = event;
|
const evt = event;
|
||||||
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
||||||
})
|
});
|
||||||
.attr('stroke', (datum) => {
|
|
||||||
return datum.style.color;
|
link_enter
|
||||||
})
|
.attr('stroke', '#000')
|
||||||
.attr('stroke-width', (datum) => {
|
.attr('stroke-width', '2')
|
||||||
return datum.style.width;
|
.on('contextmenu', (datum) => {
|
||||||
})
|
let link: MapLink = (datum as unknown) as MapLink;
|
||||||
.attr('stroke-dasharray', (datum) => {
|
const evt = event;
|
||||||
return StyleTranslator.getLinkStyle(datum.style);
|
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
||||||
});
|
});
|
||||||
|
|
||||||
const link_merge = link.merge(link_enter);
|
const link_merge = link.merge(link_enter);
|
||||||
|
@ -4,27 +4,19 @@ import { LinkContextMenu } from '../../events/event-source';
|
|||||||
import { MapLink } from '../../models/map/map-link';
|
import { MapLink } from '../../models/map/map-link';
|
||||||
import { SVGSelection } from '../../models/types';
|
import { SVGSelection } from '../../models/types';
|
||||||
import { Widget } from '../widget';
|
import { Widget } from '../widget';
|
||||||
import { LinkStyle } from '../../../models/link-style';
|
|
||||||
import { StyleTranslator} from './style-translator';
|
|
||||||
|
|
||||||
class SerialLinkPath {
|
class SerialLinkPath {
|
||||||
constructor(
|
constructor(
|
||||||
public source: [number, number],
|
public source: [number, number],
|
||||||
public source_angle: [number, number],
|
public source_angle: [number, number],
|
||||||
public target_angle: [number, number],
|
public target_angle: [number, number],
|
||||||
public target: [number, number],
|
public target: [number, number]
|
||||||
public style: LinkStyle
|
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SerialLinkWidget implements Widget {
|
export class SerialLinkWidget implements Widget {
|
||||||
public onContextMenu = new EventEmitter<LinkContextMenu>();
|
public onContextMenu = new EventEmitter<LinkContextMenu>();
|
||||||
private defaultSerialLinkStyle : LinkStyle = {
|
|
||||||
color: "#B22222",
|
|
||||||
width: 2,
|
|
||||||
type: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
@ -55,12 +47,7 @@ export class SerialLinkWidget implements Widget {
|
|||||||
target.y - dy / 2.0 - 15 * vect_rot[1],
|
target.y - dy / 2.0 - 15 * vect_rot[1],
|
||||||
];
|
];
|
||||||
|
|
||||||
return new SerialLinkPath(
|
return new SerialLinkPath([source.x, source.y], angle_source, angle_target, [target.x, target.y]);
|
||||||
[source.x, source.y],
|
|
||||||
angle_source,
|
|
||||||
angle_target,
|
|
||||||
[target.x, target.y],
|
|
||||||
link.link_style.color ? link.link_style : this.defaultSerialLinkStyle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
@ -81,16 +68,7 @@ export class SerialLinkWidget implements Widget {
|
|||||||
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
this.onContextMenu.emit(new LinkContextMenu(evt, link));
|
||||||
});
|
});
|
||||||
|
|
||||||
link_enter
|
link_enter.attr('stroke', '#B22222').attr('fill', 'none').attr('stroke-width', '2');
|
||||||
.attr('stroke', (datum) => {
|
|
||||||
return datum.style.color;
|
|
||||||
})
|
|
||||||
.attr('stroke-width', (datum) => {
|
|
||||||
return datum.style.width;
|
|
||||||
})
|
|
||||||
.attr('stroke-dasharray', (datum) => {
|
|
||||||
return StyleTranslator.getLinkStyle(datum.style);
|
|
||||||
});
|
|
||||||
|
|
||||||
const link_merge = link.merge(link_enter);
|
const link_merge = link.merge(link_enter);
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import { LinkStyle } from '../../../models/link-style';
|
|
||||||
|
|
||||||
export class StyleTranslator {
|
|
||||||
static getLinkStyle(linkStyle: LinkStyle) {
|
|
||||||
if (linkStyle.type == 1) {
|
|
||||||
return `10, 10`
|
|
||||||
}
|
|
||||||
if (linkStyle.type == 2) {
|
|
||||||
return `${linkStyle.width}, ${linkStyle.width}`
|
|
||||||
}
|
|
||||||
if (linkStyle.type == 3) {
|
|
||||||
return `20, 10, ${linkStyle.width}, ${linkStyle.width}, ${linkStyle.width}, 10`
|
|
||||||
}
|
|
||||||
return `0, 0`
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,21 +31,19 @@ describe('NodesWidget', () => {
|
|||||||
const drew = svg.canvas.selectAll<SVGGElement, MapNode>('g.node');
|
const drew = svg.canvas.selectAll<SVGGElement, MapNode>('g.node');
|
||||||
const drewNode = drew.nodes()[0];
|
const drewNode = drew.nodes()[0];
|
||||||
|
|
||||||
if (drewNode != undefined && drewNode != null) {
|
drewNode.dispatchEvent(
|
||||||
drewNode.dispatchEvent(
|
new MouseEvent('mousedown', {
|
||||||
new MouseEvent('mousedown', {
|
clientX: 150,
|
||||||
clientX: 150,
|
clientY: 250,
|
||||||
clientY: 250,
|
relatedTarget: drewNode,
|
||||||
relatedTarget: drewNode,
|
screenY: 1024,
|
||||||
screenY: 1024,
|
screenX: 1024,
|
||||||
screenX: 1024,
|
view: window,
|
||||||
view: window,
|
})
|
||||||
})
|
);
|
||||||
);
|
|
||||||
|
|
||||||
window.dispatchEvent(new MouseEvent('mousemove', { clientX: 300, clientY: 300 }));
|
window.dispatchEvent(new MouseEvent('mousemove', { clientX: 300, clientY: 300 }));
|
||||||
window.dispatchEvent(new MouseEvent('mouseup', { clientX: 300, clientY: 300, view: window }));
|
window.dispatchEvent(new MouseEvent('mouseup', { clientX: 300, clientY: 300, view: window }));
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -56,9 +54,6 @@ describe('NodesWidget', () => {
|
|||||||
node.height = 100;
|
node.height = 100;
|
||||||
node.label = new MapLabel();
|
node.label = new MapLabel();
|
||||||
});
|
});
|
||||||
it('draggable behaviour', () => {
|
|
||||||
tryToDrag()
|
|
||||||
})
|
|
||||||
|
|
||||||
// it('should be draggable when enabled', () => {
|
// it('should be draggable when enabled', () => {
|
||||||
// widget.setDraggingEnabled(true);
|
// widget.setDraggingEnabled(true);
|
||||||
|
@ -4,6 +4,7 @@ import { MapSettingsService } from '../../services/mapsettings.service';
|
|||||||
import { ClickedDataEvent } from '../events/event-source';
|
import { ClickedDataEvent } from '../events/event-source';
|
||||||
import { NodeClicked, NodeContextMenu } from '../events/nodes';
|
import { NodeClicked, NodeContextMenu } from '../events/nodes';
|
||||||
import { NodesEventSource } from '../events/nodes-event-source';
|
import { NodesEventSource } from '../events/nodes-event-source';
|
||||||
|
import { GraphDataManager } from '../managers/graph-data-manager';
|
||||||
import { SelectionManager } from '../managers/selection-manager';
|
import { SelectionManager } from '../managers/selection-manager';
|
||||||
import { MapNode } from '../models/map/map-node';
|
import { MapNode } from '../models/map/map-node';
|
||||||
import { SVGSelection } from '../models/types';
|
import { SVGSelection } from '../models/types';
|
||||||
@ -17,6 +18,7 @@ export class NodeWidget implements Widget {
|
|||||||
public onNodeClicked = new EventEmitter<NodeClicked>();
|
public onNodeClicked = new EventEmitter<NodeClicked>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private graphDataManager: GraphDataManager,
|
||||||
private selectionManager: SelectionManager,
|
private selectionManager: SelectionManager,
|
||||||
private labelWidget: LabelWidget,
|
private labelWidget: LabelWidget,
|
||||||
private nodesEventSource: NodesEventSource,
|
private nodesEventSource: NodesEventSource,
|
||||||
|
@ -14,12 +14,8 @@ describe('NodesWidget', () => {
|
|||||||
nodeWidget = instance(mock(NodeWidget));
|
nodeWidget = instance(mock(NodeWidget));
|
||||||
widget = new NodesWidget(nodeWidget, new MapSettingsManager());
|
widget = new NodesWidget(nodeWidget, new MapSettingsManager());
|
||||||
});
|
});
|
||||||
it('draggable behaviour', () => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
svg.destroy();
|
svg.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -18,8 +18,8 @@ describe('ToasterErrorHandler', () => {
|
|||||||
let toasterService: MockedToasterService;
|
let toasterService: MockedToasterService;
|
||||||
let settingsService: SettingsService;
|
let settingsService: SettingsService;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: ToasterService, useClass: MockedToasterService },
|
{ provide: ToasterService, useClass: MockedToasterService },
|
||||||
{ provide: SettingsService},
|
{ provide: SettingsService},
|
||||||
|
@ -1,31 +1,15 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
||||||
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
||||||
import { ProgressDialogComponent } from './progress-dialog.component';
|
import { ProgressDialogComponent } from './progress-dialog.component';
|
||||||
|
|
||||||
describe('ProgressDialogComponent', () => {
|
describe('ProgressDialogComponent', () => {
|
||||||
let component: ProgressDialogComponent;
|
let component: ProgressDialogComponent;
|
||||||
let fixture: ComponentFixture<ProgressDialogComponent>;
|
let fixture: ComponentFixture<ProgressDialogComponent>;
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ProgressDialogComponent],
|
declarations: [ProgressDialogComponent],
|
||||||
imports:[
|
|
||||||
MatIconModule,
|
|
||||||
MatToolbarModule,
|
|
||||||
MatMenuModule,
|
|
||||||
MatCheckboxModule,
|
|
||||||
MatDialogModule
|
|
||||||
],
|
|
||||||
providers:[
|
|
||||||
{ provide: MatDialogRef, useValue: {}},
|
|
||||||
{ provide: MAT_DIALOG_DATA, useValue: {}},
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ProgressDialogComponent);
|
fixture = TestBed.createComponent(ProgressDialogComponent);
|
||||||
@ -33,7 +17,7 @@ describe('ProgressDialogComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
// it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
// expect(component).toBeTruthy();
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
import { inject, TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
|
||||||
import { MockedProgressService } from 'app/components/project-map/project-map.component.spec';
|
|
||||||
import { ProgressDialogService } from './progress-dialog.service';
|
import { ProgressDialogService } from './progress-dialog.service';
|
||||||
|
|
||||||
describe('ProgressDialogService', () => {
|
describe('ProgressDialogService', () => {
|
||||||
let mockedProgressService : MockedProgressService
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
// imports:[ProgressDialogService],
|
providers: [ProgressDialogService],
|
||||||
providers: [
|
|
||||||
{ provide: MatDialog, useValue: {} },
|
|
||||||
{ provide: ProgressDialogService, useClass:MockedProgressService },
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be created', inject([ProgressDialogService], (service: ProgressDialogService) => {
|
// it('should be created', inject([ProgressDialogService], (service: ProgressDialogService) => {
|
||||||
expect(service).toBeTruthy();
|
// expect(service).toBeTruthy();
|
||||||
}));
|
// }));
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
@ -23,8 +23,8 @@ describe('ProgressComponent', () => {
|
|||||||
let progressService: ProgressService;
|
let progressService: ProgressService;
|
||||||
let router: MockedRouter = new MockedRouter();
|
let router: MockedRouter = new MockedRouter();
|
||||||
|
|
||||||
beforeEach(async() => {
|
beforeEach(async(() => {
|
||||||
await TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [RouterTestingModule, MatProgressSpinnerModule, MatIconModule],
|
imports: [RouterTestingModule, MatProgressSpinnerModule, MatIconModule],
|
||||||
providers: [ProgressService, { provide: Router, useValue: router }],
|
providers: [ProgressService, { provide: Router, useValue: router }],
|
||||||
declarations: [ProgressComponent],
|
declarations: [ProgressComponent],
|
||||||
@ -32,7 +32,7 @@ describe('ProgressComponent', () => {
|
|||||||
|
|
||||||
progressService = TestBed.get(ProgressService);
|
progressService = TestBed.get(ProgressService);
|
||||||
router = TestBed.get(Router);
|
router = TestBed.get(Router);
|
||||||
});
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ProgressComponent);
|
fixture = TestBed.createComponent(ProgressComponent);
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { UploadServiceService } from './upload-service.service';
|
|
||||||
|
|
||||||
describe('UploadServiceService', () => {
|
|
||||||
let service: UploadServiceService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({});
|
|
||||||
service = TestBed.inject(UploadServiceService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,23 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { BehaviorSubject, Subject } from 'rxjs';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class UploadServiceService {
|
|
||||||
|
|
||||||
private countSource = new Subject();
|
|
||||||
currentCount = this.countSource.asObservable();
|
|
||||||
private cancelItem = new Subject();
|
|
||||||
currentCancelItemDetails = this.cancelItem.asObservable();
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
processBarCount(processCount:number) {
|
|
||||||
this.countSource.next(processCount)
|
|
||||||
}
|
|
||||||
cancelFileUploading(isCancel){
|
|
||||||
this.cancelItem.next(isCancel)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
<p>{{upload_file_type}} Uploading please wait .... {{uploadProgress}}%</p>
|
|
||||||
<div class="row proccessBar-row ">
|
|
||||||
<div class="col-md-9 proccessBar-col">
|
|
||||||
<mat-progress-bar mode="determinate" [value]="uploadProgress" aria-valuemin="0" aria-valuemax="100">
|
|
||||||
</mat-progress-bar>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 proccessBar-col">
|
|
||||||
<button mat-button color="primary" (click)="cancelItem()" class="file-button">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
.mat-snack-bar-container{
|
|
||||||
min-width: 450px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.proccessBar-row{
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.proccessBar-col{
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { MatSnackBarModule, MatSnackBarRef, MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar';
|
|
||||||
import { UploadServiceService } from './upload-service.service';
|
|
||||||
|
|
||||||
import { UploadingProcessbarComponent } from './uploading-processbar.component';
|
|
||||||
|
|
||||||
describe('UploadingProcessbarComponent', () => {
|
|
||||||
let component: UploadingProcessbarComponent;
|
|
||||||
let fixture: ComponentFixture<UploadingProcessbarComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [UploadingProcessbarComponent],
|
|
||||||
imports:[MatSnackBarModule],
|
|
||||||
providers: [
|
|
||||||
{ provide: MAT_SNACK_BAR_DATA, useValue: {} },
|
|
||||||
{ provide: MatSnackBarRef, useValue: {} },
|
|
||||||
{ provide: UploadServiceService, useClass: UploadServiceService },
|
|
||||||
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(UploadingProcessbarComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,45 +0,0 @@
|
|||||||
import { Component, Inject, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
|
|
||||||
import { MatSnackBarRef, MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
import { UploadServiceService } from './upload-service.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-uploading-processbar',
|
|
||||||
templateUrl: './uploading-processbar.component.html',
|
|
||||||
styleUrls: ['./uploading-processbar.component.scss'],
|
|
||||||
encapsulation: ViewEncapsulation.None,
|
|
||||||
|
|
||||||
})
|
|
||||||
export class UploadingProcessbarComponent implements OnInit {
|
|
||||||
uploadProgress: number = 0
|
|
||||||
subscription: Subscription;
|
|
||||||
upload_file_type:string
|
|
||||||
constructor(
|
|
||||||
@Inject(MAT_SNACK_BAR_DATA) public data,
|
|
||||||
private _snackRef: MatSnackBarRef<UploadingProcessbarComponent>,
|
|
||||||
private _US: UploadServiceService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.upload_file_type = this.data.upload_file_type
|
|
||||||
this.subscription = this._US.currentCount.subscribe((count:number) => {
|
|
||||||
this.uploadProgress = count;
|
|
||||||
if (this.uploadProgress === 100 || this.uploadProgress == null ) {
|
|
||||||
this.dismiss()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dismiss() {
|
|
||||||
this._snackRef.dismiss();
|
|
||||||
}
|
|
||||||
cancelItem() {
|
|
||||||
this._US.cancelFileUploading(true)
|
|
||||||
}
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.subscription.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
<div class="content" *ngIf="isReady; else loading">
|
|
||||||
<div class="default-header">
|
|
||||||
<div class="row">
|
|
||||||
<h1 class="col">Access Control List (ACL)</h1>
|
|
||||||
<button class="col" mat-raised-button color="primary" (click)="deleteMultiple()" class="add-ace-button" [disabled]="selection.selected.length == 0">
|
|
||||||
Delete selected ACEs
|
|
||||||
</button>
|
|
||||||
<button class="col" mat-raised-button color="primary" (click)="addACE()" class="add-ace-button">
|
|
||||||
Add ACE
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<mat-form-field class="full-width">
|
|
||||||
<input matInput placeholder="Search by path, user/group or role" [(ngModel)]="searchText"
|
|
||||||
[ngModelOptions]="{ standalone: true }"/>
|
|
||||||
</mat-form-field>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div class="default-content">
|
|
||||||
<table mat-table [dataSource]="dataSource | aceFilter: searchText:endpoints " class="mat-elevation-z8" matSort #acesSort="matSort">
|
|
||||||
|
|
||||||
<ng-container matColumnDef="select" >
|
|
||||||
<th mat-header-cell *matHeaderCellDef class="small-col">
|
|
||||||
<mat-checkbox (change)="$event ? masterToggle() : null"
|
|
||||||
[checked]="selection.hasValue() && isAllSelected()"
|
|
||||||
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
|
||||||
</mat-checkbox>
|
|
||||||
</th>
|
|
||||||
<td mat-cell *matCellDef="let row" class="small-col">
|
|
||||||
<mat-checkbox (click)="$event.stopPropagation()"
|
|
||||||
(change)="$event ? selection.toggle(row) : null"
|
|
||||||
[checked]="selection.isSelected(row)">
|
|
||||||
</mat-checkbox>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="path">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Path</th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{getNameByUuidFromEndpoint(element.path)}} </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="user/group">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>User/Group</th>
|
|
||||||
<td mat-cell *matCellDef="let element">
|
|
||||||
<div *ngIf="element.ace_type === 'user' else groupId">{{getNameByUuidFromEndpoint(element.user_id)}}</div>
|
|
||||||
<ng-template #groupId>{{getNameByUuidFromEndpoint(element.group_id)}}</ng-template>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="role">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Role</th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{getNameByUuidFromEndpoint(element.role_id)}} </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="propagate">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Propagate</th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{element.propagate}} </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="allowed">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Allowed</th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{element.allowed}} </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="created_at">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Created</th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{element.created_at}} </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="updated_at">
|
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Last update</th>
|
|
||||||
<td mat-cell *matCellDef="let element"> {{element.updated_at}} </td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="delete">
|
|
||||||
<th mat-header-cell *matHeaderCellDef> </th>
|
|
||||||
<td mat-cell *matCellDef="let element"><button mat-button (click)="onDelete(element)"><mat-icon>delete</mat-icon></button></td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
|
||||||
|
|
||||||
|
|
||||||
</table>
|
|
||||||
<mat-paginator #acesPaginator="matPaginator"
|
|
||||||
[pageSizeOptions]="[5, 10, 20]"
|
|
||||||
showFirstLastButtons
|
|
||||||
aria-label="Select page">
|
|
||||||
</mat-paginator>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ng-template #loading>
|
|
||||||
<div>
|
|
||||||
<mat-spinner class="loader"></mat-spinner>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
@ -1,26 +0,0 @@
|
|||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-width {
|
|
||||||
width: 940px;
|
|
||||||
margin-left: -470px;
|
|
||||||
left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-ace-button {
|
|
||||||
height: 40px;
|
|
||||||
width: 160px;
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
position: absolute;
|
|
||||||
margin: auto;
|
|
||||||
height: 175px;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 175px;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AclManagementComponent } from './acl-management.component';
|
|
||||||
|
|
||||||
describe('AclManagementComponent', () => {
|
|
||||||
let component: AclManagementComponent;
|
|
||||||
let fixture: ComponentFixture<AclManagementComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ AclManagementComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AclManagementComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,176 +0,0 @@
|
|||||||
/*
|
|
||||||
* Software Name : GNS3 Web UI
|
|
||||||
* Version: 3
|
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2023 Orange Business Services
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* This software is distributed under the GPL-3.0 or any later version,
|
|
||||||
* the text of which is available at https://www.gnu.org/licenses/gpl-3.0.txt
|
|
||||||
* or see the "LICENSE" file for more details.
|
|
||||||
*
|
|
||||||
* Author: Sylvain MATHIEU, Elise LEBEAU
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Component, OnInit, QueryList, ViewChildren} from '@angular/core';
|
|
||||||
import {Controller} from "@models/controller";
|
|
||||||
import {SelectionModel} from "@angular/cdk/collections";
|
|
||||||
import {Group} from "@models/groups/group";
|
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
|
||||||
import {ACE} from "@models/api/ACE";
|
|
||||||
import {ActivatedRoute} from "@angular/router";
|
|
||||||
import {ControllerService} from "@services/controller.service";
|
|
||||||
import {ToasterService} from "@services/toaster.service";
|
|
||||||
import {GroupService} from "@services/group.service";
|
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
|
||||||
import {AclService} from "@services/acl.service";
|
|
||||||
import {MatPaginator} from "@angular/material/paginator";
|
|
||||||
import {MatSort} from "@angular/material/sort";
|
|
||||||
import {AddUserDialogComponent} from "@components/user-management/add-user-dialog/add-user-dialog.component";
|
|
||||||
import {AddAceDialogComponent} from "@components/acl-management/add-ace-dialog/add-ace-dialog.component";
|
|
||||||
import {DeleteUserDialogComponent} from "@components/user-management/delete-user-dialog/delete-user-dialog.component";
|
|
||||||
import {DeleteAceDialogComponent} from "@components/acl-management/delete-ace-dialog/delete-ace-dialog.component";
|
|
||||||
import {User} from "@models/users/user";
|
|
||||||
import {Endpoint} from "@models/api/endpoint";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-acl-management',
|
|
||||||
templateUrl: './acl-management.component.html',
|
|
||||||
styleUrls: ['./acl-management.component.scss']
|
|
||||||
})
|
|
||||||
export class AclManagementComponent implements OnInit {
|
|
||||||
|
|
||||||
|
|
||||||
@ViewChildren('acesPaginator') acesPaginator: QueryList<MatPaginator>;
|
|
||||||
@ViewChildren('acesSort') acesSort: QueryList<MatSort>;
|
|
||||||
controller: Controller;
|
|
||||||
public displayedColumns = ['select', 'path', 'user/group', 'role', 'propagate', 'allowed', 'updated_at', 'delete'];
|
|
||||||
selection = new SelectionModel<ACE>(true, []);
|
|
||||||
aces: ACE[];
|
|
||||||
dataSource = new MatTableDataSource<ACE>();
|
|
||||||
isReady = false;
|
|
||||||
searchText = '';
|
|
||||||
endpoints: Endpoint[];
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
|
||||||
private controllerService: ControllerService,
|
|
||||||
private toasterService: ToasterService,
|
|
||||||
public aclService: AclService,
|
|
||||||
public dialog: MatDialog) { }
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
const controllerId = this.route.parent.snapshot.paramMap.get('controller_id');
|
|
||||||
this.controllerService.get(+controllerId).then((controller: Controller) => {
|
|
||||||
this.controller = controller;
|
|
||||||
this.aclService.getEndpoints(this.controller)
|
|
||||||
.subscribe((endpoints: Endpoint[]) => {
|
|
||||||
this.endpoints = endpoints
|
|
||||||
this.refresh();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
|
||||||
this.acesPaginator.changes.subscribe((comps: QueryList <MatPaginator>) =>
|
|
||||||
{
|
|
||||||
this.dataSource.paginator = comps.first;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.acesSort.changes.subscribe((comps: QueryList<MatSort>) => {
|
|
||||||
this.dataSource.sort = comps.first;
|
|
||||||
})
|
|
||||||
|
|
||||||
this.dataSource.sortingDataAccessor = (item, property) => {
|
|
||||||
switch (property) {
|
|
||||||
case 'path':
|
|
||||||
case 'user/group':
|
|
||||||
case 'role':
|
|
||||||
return item[property] ? item[property].toLowerCase() : '';
|
|
||||||
default:
|
|
||||||
return item[property];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
this.aclService.list(this.controller).subscribe((aces: ACE[]) => {
|
|
||||||
this.isReady = true;
|
|
||||||
this.aces = aces
|
|
||||||
this.dataSource.data = aces;
|
|
||||||
this.selection.clear();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addACE() {
|
|
||||||
const dialogRef = this.dialog.open(AddAceDialogComponent, {
|
|
||||||
width: '1200px',
|
|
||||||
height: '500px',
|
|
||||||
autoFocus: false,
|
|
||||||
disableClose: true,
|
|
||||||
data: {endpoints: this.endpoints}
|
|
||||||
});
|
|
||||||
let instance = dialogRef.componentInstance;
|
|
||||||
instance.controller = this.controller;
|
|
||||||
dialogRef.afterClosed().subscribe(() => this.refresh());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onDelete(ace: ACE) {
|
|
||||||
this.dialog
|
|
||||||
.open(DeleteAceDialogComponent, {width: '500px', data: {aces: [ace]}})
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe((isDeletedConfirm) => {
|
|
||||||
if (isDeletedConfirm) {
|
|
||||||
this.aclService.delete(this.controller, ace.ace_id)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.refresh()
|
|
||||||
}, (error) => {
|
|
||||||
this.toasterService.error(`An error occur while trying to delete ace ${ace.ace_id}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isAllSelected() {
|
|
||||||
const numSelected = this.selection.selected.length;
|
|
||||||
const numRows = this.aces.length;
|
|
||||||
return numSelected === numRows;
|
|
||||||
}
|
|
||||||
|
|
||||||
masterToggle() {
|
|
||||||
this.isAllSelected() ?
|
|
||||||
this.selection.clear() :
|
|
||||||
this.aces.forEach(row => this.selection.select(row));
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteMultiple() {
|
|
||||||
this.dialog
|
|
||||||
.open(DeleteAceDialogComponent, {width: '500px', data: {aces: this.selection.selected}})
|
|
||||||
.afterClosed()
|
|
||||||
.subscribe((isDeletedConfirm) => {
|
|
||||||
if (isDeletedConfirm) {
|
|
||||||
this.selection.selected.forEach((ace: ACE) => {
|
|
||||||
this.aclService.delete(this.controller, ace.ace_id)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.refresh()
|
|
||||||
}, (error) => {
|
|
||||||
this.toasterService.error(`An error occur while trying to delete ace ${ace.ace_id}`);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
this.selection.clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getNameByUuidFromEndpoint(uuid: string): string {
|
|
||||||
if (this.endpoints) {
|
|
||||||
const elt = this.endpoints.filter((endpoint: Endpoint) => endpoint.endpoint.includes(uuid))
|
|
||||||
if (elt.length >= 1) {
|
|
||||||
return elt[0].name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|