diff --git a/.appveyor.yml b/.appveyor.yml index 792bc9b6..3e291170 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,6 +20,7 @@ install: build_script: - cmd: set NODE_OPTIONS=--max-old-space-size=8092 - yarn buildforelectron + - "%PYTHON%\\python.exe -m pip install -U pip" - "%PYTHON%\\python.exe -m pip install -r scripts\\requirements.txt" - "%PYTHON%\\python.exe scripts\\build.py download -a" - "%PYTHON%\\python.exe scripts\\build.py build_exe -b dist/exe.gns3server -s" diff --git a/.circleci/config.yml b/.circleci/config.yml index 6417b6eb..c33460ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,9 @@ # iOS CircleCI 2.1 configuration file version: 2.1 + +orbs: + node: circleci/node@4.2.0 + jobs: build: macos: @@ -7,13 +11,16 @@ jobs: steps: - checkout + - node/install: + install-yarn: true - run: - name: Install nodejs + name: Update BREW and print configs command: | brew update - brew upgrade yarn - brew upgrade node + brew analytics off + brew --env + brew --config - run: name: Set timezone and check current datetime @@ -34,6 +41,8 @@ jobs: curl -o /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/b1bd1c4a62e1336422de3614d1fc49ffbce589a8/Formula/readline.rb # remove check for old compilers which creates the error described in https://github.com/sashkab/homebrew-python/issues/36 sed -i.bak -e '58,61d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb + # remove 'do devel' block to avoid error: Calling 'devel' blocks in formulae is disabled! + sed -i.bak -e '14,17d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb brew unlink python brew uninstall --ignore-dependencies readline brew install readline @@ -41,7 +50,7 @@ jobs: brew pin readline # --ignore-dependencies is used to prevent this issue: https://github.com/tensorflow/tensorflow/issues/25093 brew install --ignore-dependencies python - brew switch python 3.6.5_1 + #brew link python 3.6.5_1 brew info python brew pin python @@ -77,8 +86,11 @@ jobs: name: Building gns3server command: | python3 -V - pip3 install -r scripts/requirements.txt + python3 -m pip install -U pip + python3 -m pip install -r scripts/requirements.txt python3 scripts/build.py download -a + # necessary because of https://github.com/GNS3/gns3-gui/issues/2849 + python3 -m pip install jsonschema==2.6.0 python3 scripts/build.py build_exe -b dist/exe.gns3server -s python3 scripts/build.py validate -b dist @@ -105,4 +117,3 @@ workflows: filters: tags: only: /v.*/ - diff --git a/.travis.yml b/.travis.yml index 4c657dfa..c5cfcfca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,12 +37,12 @@ before_install: before_script: # greenkeeper-lockfile support - greenkeeper-lockfile-update - - npm install -g codecov + # - npm install -g codecov script: yarn coverage after_success: - - codecov + # - codecov after_script: # greenkeeper-lockfile support diff --git a/README.md b/README.md index 97f8f893..25529e3e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![Travis CI](https://api.travis-ci.org/GNS3/gns3-web-ui.svg?branch=master)](https://travis-ci.org) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/GNS3/gns3-web-ui?branch=master&svg=true)](https://www.appveyor.com/) [![CircleCI](https://circleci.com/gh/GNS3/gns3-web-ui/tree/master.png)](https://circleci.com/gh/GNS3/gns3-web-ui/tree/master.png) -[![codecov](https://codecov.io/gh/GNS3/gns3-web-ui/branch/master/graph/badge.svg)](https://codecov.io/gh/GNS3/gns3-web-ui) [![Dependency](https://img.shields.io/librariesio/github/GNS3/gns3-web-ui)](https://libraries.io/github/GNS3/gns3-web-ui) [![Packages versions](https://repology.org/badge/latest-versions/gns3.svg)](https://repology.org/metapackage/gns3/versions) @@ -28,6 +27,14 @@ We're using [yarn](https://yarnpkg.com/lang/en/) for packages installation: yarn install ``` +## JavaScript heap out of memory + +Increase the memory allocated to Node if you get JavaScript heap out of memory errors. + +``` +export NODE_OPTIONS=--max-old-space-size=8192 +``` + #### Run GNS3 server Visit [gns3-server](https://github.com/GNS3/gns3-server) for guide how to run GNS3 server. diff --git a/angular.json b/angular.json index caba6592..6b7e8338 100644 --- a/angular.json +++ b/angular.json @@ -25,7 +25,12 @@ "@mattlewis92/dom-autoscroller", "rxjs/Rx", "rxjs/add/operator/map", - "rxjs-compat/add/operator/map" + "rxjs-compat/add/operator/map", + "angular-react-core.js", + "react", + "react-dom", + "classnames", + "stylenames" ], "aot": true, "outputPath": "dist", @@ -42,16 +47,7 @@ "node_modules/bootstrap/dist/css/bootstrap.min.css", "node_modules/notosans-fontface/css/notosans-fontface.min.css", "src/styles.scss", - { - "inject": true, - "input": "src/theme.scss", - "bundleName": "theme-default-dark" - }, - { - "inject": true, - "input": "src/theme-light.scss", - "bundleName": "theme-default" - } + "src/theme.scss" ], "scripts": [] }, @@ -185,9 +181,6 @@ "assets": [ "src/assets", "src/favicon.ico" - ], - "codeCoverageExclude": [ - "src/app/cartography/components/experimental-map/**/*" ] } }, diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts index 7e2a1898..217ef4e7 100644 --- a/e2e/app.e2e-spec.ts +++ b/e2e/app.e2e-spec.ts @@ -10,7 +10,7 @@ describe('GNS3 Web UI Application', () => { it('should have correct page title', async () => { // arrange await page.navigateTo(); - + // act let text = await page.getTitleText(); diff --git a/e2e/helpers/common.po.ts b/e2e/helpers/common.po.ts index 3dae8252..e40e30be 100644 --- a/e2e/helpers/common.po.ts +++ b/e2e/helpers/common.po.ts @@ -1,22 +1,21 @@ -import { browser, by, element } from 'protractor'; -import { ServersPage } from './server.po'; +import { browser } from 'protractor'; export class TestHelper { - sleep(value: number) { - browser.sleep(value); - } + sleep(value: number) { + browser.sleep(value); + } - waitForLoading() { - browser.waitForAngular(); - } + waitForLoading() { + browser.waitForAngular(); + } - async asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array); - } + async asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array); } + } - getCurrentUrl() { - return browser.getCurrentUrl(); - } + getCurrentUrl() { + return browser.getCurrentUrl(); + } } diff --git a/e2e/helpers/project-map.po.ts b/e2e/helpers/project-map.po.ts index 7ce8c823..3e5c9e06 100644 --- a/e2e/helpers/project-map.po.ts +++ b/e2e/helpers/project-map.po.ts @@ -1,50 +1,50 @@ -import { TestHelper } from "./common.po" -import { browser, by } from "protractor"; +import { browser, by } from 'protractor'; +import { TestHelper } from './common.po'; export class ProjectMapPage { - helper = new TestHelper(); + helper = new TestHelper(); - async openAddProjectDialog() { - let addButton = await browser.driver.findElement(by.css('button.addNode')); - await addButton.click(); + async openAddProjectDialog() { + let addButton = await browser.driver.findElement(by.css('button.addNode')); + await addButton.click(); + } + + async addNode() { + let inputs = await browser.driver.findElements(by.css('input.mat-input-element')); + await inputs[0].sendKeys('VPCS'); + this.helper.sleep(1000); + + let selects = await browser.driver.findElements(by.css('mat-select.mat-select')); + await selects[1].click(); + this.helper.sleep(1000); + + let options = await browser.driver.findElements(by.css('mat-option.mat-option')); + await options[1].click(); //first option should be chosen + this.helper.sleep(1000); + + // new select appears after refreshing data + selects = await browser.driver.findElements(by.css('mat-select.mat-select')); + if (selects[2]) { + await selects[2].click(); + this.helper.sleep(1000); + + options = await browser.driver.findElements(by.css('mat-option.mat-option')); + await options[0].click(); + this.helper.sleep(1000); } - async addNode() { - let inputs = await browser.driver.findElements(by.css('input.mat-input-element')); - await inputs[0].sendKeys('VPCS'); - this.helper.sleep(1000); + let addButton = await browser.driver.findElement(by.css('button.addButton')); + await addButton.click(); + this.helper.sleep(1000); + } - let selects = await browser.driver.findElements(by.css('mat-select.mat-select')); - await selects[1].click(); - this.helper.sleep(1000); + async verifyIfNodeWithLabelExists(labelToFind: string) { + this.helper.sleep(5000); + let nodeLabel = await browser.driver.findElement(by.css('#map > g > g.layer > g.nodes > g > g > g > g > text')); + let selectedNode; + let textFromNodeLabel = await nodeLabel.getText(); + if (textFromNodeLabel == labelToFind) selectedNode = nodeLabel; - let options = await browser.driver.findElements(by.css('mat-option.mat-option')); - await options[1].click(); //first option should be chosen - this.helper.sleep(1000); - - // new select appears after refreshing data - selects = await browser.driver.findElements(by.css('mat-select.mat-select')); - if (selects[2]) { - await selects[2].click(); - this.helper.sleep(1000); - - options = await browser.driver.findElements(by.css('mat-option.mat-option')); - await options[0].click(); - this.helper.sleep(1000); - } - - let addButton = await browser.driver.findElement(by.css('button.addButton')); - await addButton.click(); - this.helper.sleep(1000); - } - - async verifyIfNodeWithLabelExists(labelToFind: string) { - this.helper.sleep(5000); - let nodeLabel = await browser.driver.findElement(by.css('#map > g > g.layer > g.nodes > g > g > g > g > text')); - let selectedNode; - let textFromNodeLabel = await nodeLabel.getText(); - if (textFromNodeLabel == labelToFind) selectedNode = nodeLabel; - - return selectedNode ? true : false; - } + return selectedNode ? true : false; + } } diff --git a/e2e/helpers/project.po.ts b/e2e/helpers/project.po.ts index 76b60ec2..5288d917 100644 --- a/e2e/helpers/project.po.ts +++ b/e2e/helpers/project.po.ts @@ -1,20 +1,20 @@ -import { TestHelper } from "./common.po" -import { browser, by } from "protractor"; +import { browser, by } from 'protractor'; +import { TestHelper } from './common.po'; export class ProjectsPage { - helper = new TestHelper(); + helper = new TestHelper(); - async openAddProjectDialog() { - let addButton = await browser.driver.findElement(by.css('button.add-button')); - await addButton.click(); - } + async openAddProjectDialog() { + let addButton = await browser.driver.findElement(by.css('button.add-button')); + await addButton.click(); + } - async createProject() { - let today = new Date(); - let inputs = await browser.driver.findElements(by.css('input.mat-input-element')); - await inputs[1].sendKeys('test project ' + today.getUTCMilliseconds()); - this.helper.sleep(2000); - let dialogButton = await browser.driver.findElement(by.css('button.add-project-button')); - await dialogButton.click(); - } + async createProject() { + let today = new Date(); + let inputs = await browser.driver.findElements(by.css('input.mat-input-element')); + await inputs[1].sendKeys('test project ' + today.getUTCMilliseconds()); + this.helper.sleep(2000); + let dialogButton = await browser.driver.findElement(by.css('button.add-project-button')); + await dialogButton.click(); + } } diff --git a/e2e/helpers/server.po.ts b/e2e/helpers/server.po.ts index ece2422b..90250c7e 100644 --- a/e2e/helpers/server.po.ts +++ b/e2e/helpers/server.po.ts @@ -1,41 +1,41 @@ -import { browser, by, element } from 'protractor'; +import { browser, by } from 'protractor'; import { TestHelper } from './common.po'; export class ServersPage { - helper = new TestHelper; + helper = new TestHelper(); - maximizeWindow() { - browser.driver.manage().window().maximize(); - } + maximizeWindow() { + browser.driver.manage().window().maximize(); + } - navigateToServersPage() { - return browser.get('/servers'); - } + navigateToServersPage() { + return browser.get('/servers'); + } - getAddServerNotificationText() { - return browser.driver.findElement(by.className('mat-card-content')).getText(); - } + getAddServerNotificationText() { + return browser.driver.findElement(by.className('mat-card-content')).getText(); + } - async clickAddServer() { - let serversTable = await this.checkServersTable(); - if (serversTable.length === 0) { - let buttons = await browser.driver.findElements(by.className('mat-button mat-button-base')); - await buttons[3].click(); - } + async clickAddServer() { + let serversTable = await this.checkServersTable(); + if (serversTable.length === 0) { + let buttons = await browser.driver.findElements(by.className('mat-button mat-button-base')); + await buttons[3].click(); } + } - checkServersTable() { - return browser.driver.findElements(by.css('mat-cell')); - } + checkServersTable() { + return browser.driver.findElements(by.css('mat-cell')); + } - async navigateToServerProjects() { - this.helper.sleep(2000); - let hyperlinks = await browser.driver.findElements(by.css('a.table-link')); - let serverLink; - await this.helper.asyncForEach(hyperlinks, async element => { - let text = await element.getText(); - if (text === '127.0.0.1') serverLink = element; - }); - await serverLink.click(); - } + async navigateToServerProjects() { + this.helper.sleep(2000); + let hyperlinks = await browser.driver.findElements(by.css('a.table-link')); + let serverLink; + await this.helper.asyncForEach(hyperlinks, async (element) => { + let text = await element.getText(); + if (text === '127.0.0.1') serverLink = element; + }); + await serverLink.click(); + } } diff --git a/e2e/project-map.e2e-spec.ts b/e2e/project-map.e2e-spec.ts index f5379d9d..8986d97a 100644 --- a/e2e/project-map.e2e-spec.ts +++ b/e2e/project-map.e2e-spec.ts @@ -1,41 +1,40 @@ -import { ServersPage } from './helpers/server.po'; import { TestHelper } from './helpers/common.po'; -import { element } from 'protractor'; -import { ProjectsPage } from './helpers/project.po'; import { ProjectMapPage } from './helpers/project-map.po'; +import { ProjectsPage } from './helpers/project.po'; +import { ServersPage } from './helpers/server.po'; describe('Project map page', () => { - let serversPage: ServersPage; - let projectsPage: ProjectsPage; - let projectMapPage: ProjectMapPage; - let helper: TestHelper; + let serversPage: ServersPage; + let projectsPage: ProjectsPage; + let projectMapPage: ProjectMapPage; + let helper: TestHelper; - beforeEach(async () => { - serversPage = new ServersPage(); - projectsPage = new ProjectsPage(); - projectMapPage = new ProjectMapPage(); - helper = new TestHelper(); + beforeEach(async () => { + serversPage = new ServersPage(); + projectsPage = new ProjectsPage(); + projectMapPage = new ProjectMapPage(); + helper = new TestHelper(); - serversPage.maximizeWindow(); - await serversPage.navigateToServersPage(); - await serversPage.clickAddServer(); - await serversPage.navigateToServerProjects(); - await projectsPage.openAddProjectDialog(); - helper.sleep(2000); - await projectsPage.createProject(); - helper.sleep(2000); - }); + serversPage.maximizeWindow(); + await serversPage.navigateToServersPage(); + await serversPage.clickAddServer(); + await serversPage.navigateToServerProjects(); + await projectsPage.openAddProjectDialog(); + helper.sleep(2000); + await projectsPage.createProject(); + helper.sleep(2000); + }); - it('user should have possibility to add nodes to map', async () => { - // arrange - projectMapPage.openAddProjectDialog(); - helper.sleep(2000); + it('user should have possibility to add nodes to map', async () => { + // arrange + projectMapPage.openAddProjectDialog(); + helper.sleep(2000); - //act - projectMapPage.addNode(); - helper.sleep(2000); + //act + projectMapPage.addNode(); + helper.sleep(2000); - //assert - expect(await projectMapPage.verifyIfNodeWithLabelExists('PC1')).toBe(true); - }); + //assert + expect(await projectMapPage.verifyIfNodeWithLabelExists('PC1')).toBe(true); + }); }); diff --git a/e2e/projects.e2e-spec.ts b/e2e/projects.e2e-spec.ts index 977c3656..01df6aee 100644 --- a/e2e/projects.e2e-spec.ts +++ b/e2e/projects.e2e-spec.ts @@ -1,34 +1,33 @@ -import { ServersPage } from './helpers/server.po'; import { TestHelper } from './helpers/common.po'; -import { element } from 'protractor'; import { ProjectsPage } from './helpers/project.po'; +import { ServersPage } from './helpers/server.po'; describe('Projects page', () => { - let serversPage: ServersPage; - let projectsPage: ProjectsPage; - let helper: TestHelper; + let serversPage: ServersPage; + let projectsPage: ProjectsPage; + let helper: TestHelper; - beforeEach(() => { - serversPage = new ServersPage(); - projectsPage = new ProjectsPage(); - helper = new TestHelper(); - }); + beforeEach(() => { + serversPage = new ServersPage(); + projectsPage = new ProjectsPage(); + helper = new TestHelper(); + }); - it('user should have possibility to create new project', async () => { - // arrange - serversPage.maximizeWindow(); - await serversPage.navigateToServersPage(); - await serversPage.clickAddServer(); - await serversPage.navigateToServerProjects(); - helper.sleep(2000); + it('user should have possibility to create new project', async () => { + // arrange + serversPage.maximizeWindow(); + await serversPage.navigateToServersPage(); + await serversPage.clickAddServer(); + await serversPage.navigateToServerProjects(); + helper.sleep(2000); - //act - await projectsPage.openAddProjectDialog(); - helper.sleep(2000); - await projectsPage.createProject(); - helper.sleep(2000); + //act + await projectsPage.openAddProjectDialog(); + helper.sleep(2000); + await projectsPage.createProject(); + helper.sleep(2000); - //assert - expect(helper.getCurrentUrl()).toMatch('server/1/project/'); - }); + //assert + expect(helper.getCurrentUrl()).toMatch('server/1/project/'); + }); }); diff --git a/e2e/servers.e2e-spec.ts b/e2e/servers.e2e-spec.ts index 1d177f4b..45da0436 100644 --- a/e2e/servers.e2e-spec.ts +++ b/e2e/servers.e2e-spec.ts @@ -1,44 +1,43 @@ -import { ServersPage } from './helpers/server.po'; import { TestHelper } from './helpers/common.po'; -import { element } from 'protractor'; +import { ServersPage } from './helpers/server.po'; describe('Servers page', () => { - let page: ServersPage; - let helper: TestHelper; + let page: ServersPage; + let helper: TestHelper; - beforeEach(() => { - page = new ServersPage(); - helper = new 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()); }); - 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'); - }); + // assert + expect(serverData).toContain('127.0.0.1'); + expect(serverData).toContain('3080'); + }); }); diff --git a/package.json b/package.json index 80c1529d..c2a79c42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gns3-web-ui", - "version": "2.2.18dev", + "version": "2.2.21dev", "author": { "name": "GNS3 Technology Inc.", "email": "developers@gns3.com" @@ -17,6 +17,7 @@ "start": "ng serve", "startforelectron": "ng serve --configuration=electronDev", "build": "ng build", + "buildforproduction": "ng build --source-map=false --build-optimizer --configuration=production --base-href /static/web-ui/", "buildforelectron": "ng build --configuration=electronProd", "buildforgithub": "ng build --configuration=githubProd", "test": "ng test", @@ -40,93 +41,103 @@ }, "private": true, "dependencies": { - "@angular/animations": "^11.0.8", - "@angular/cdk": "^11.0.3", - "@angular/common": "^11.0.8", - "@angular/compiler": "^11.0.8", - "@angular/core": "^11.0.8", - "@angular/forms": "^11.0.8", + "@angular-react/core": "^3.0.0", + "@angular-react/fabric": "^3.0.0", + "@angular/animations": "^11.2.8", + "@angular/cdk": "^11.2.7", + "@angular/common": "^11.2.8", + "@angular/compiler": "^11.2.8", + "@angular/core": "^11.2.8", + "@angular/forms": "^11.2.8", "@angular/http": "^7.2.16", - "@angular/material": "^11.0.3", - "@angular/platform-browser": "^11.0.8", - "@angular/platform-browser-dynamic": "^11.0.8", - "@angular/router": "^11.0.8", - "@sentry/browser": "^5.29.2", - "@types/jest": "^26.0.20", - "@types/mocha": "^8.2.0", + "@angular/material": "^11.2.7", + "@angular/platform-browser": "^11.2.8", + "@angular/platform-browser-dynamic": "^11.2.8", + "@angular/router": "^11.2.8", + "@sentry/browser": "^6.2.5", + "@types/jest": "^26.0.22", + "@types/mocha": "^8.2.2", + "@types/react": "^17.0.3", + "@types/react-dom": "^17.0.3", "angular-draggable-droppable": "^4.6.0", "angular-persistence": "^1.0.1", - "angular-resizable-element": "^3.3.4", + "angular-resizable-element": "^3.3.5", "angular2-draggable": "^2.3.2", "angular2-hotkeys": "^2.2.0", "angular2-indexeddb": "^1.2.3", - "bootstrap": "^4.5.3", + "bootstrap": "^4.6.0", "command-exists": "^1.2.9", - "core-js": "^3.8.2", - "d3-ng2-service": "^2.1.0", "marked": "^1.1.1", + "core-js": "^3.10.0", + "d3-ng2-service": "^2.2.0", + "eev": "^0.1.5", "file-saver": "^2.0.5", - "ini": "^1.3.8", + "ini": "^2.0.0", "material-design-icons": "^3.0.1", "ng-circle-progress": "^1.6.0", - "ng2-file-upload": "^1.3.0", + "ng2-file-upload": "^1.4.0", "ngx-childprocess": "^0.0.6", - "ngx-device-detector": "^2.0.5", - "ngx-electron": "^2.1.1", + "ngx-device-detector": "^2.0.6", + "ngx-electron": "^2.2.0", "node-fetch": "^2.6.1", "notosans-fontface": "1.2.2", - "rxjs": "^6.6.3", - "rxjs-compat": "^6.6.3", - "save-html-as-image": "^1.3.4", - "save-svg-as-png": "^1.4.14", - "schematics-scss-migrate": "^1.2.10", - "snyk": "^1.437.3", + "office-ui-fabric-react": "^7.166.0", + "prettier-plugin-organize-imports": "^1.1.1", + "react": "^17.0.2", + "react-bootstrap": "^1.5.2", + "react-dom": "^17.0.2", + "rxjs": "^6.6.7", + "rxjs-compat": "^6.6.7", + "save-html-as-image": "^1.5.2", + "save-svg-as-png": "^1.4.17", + "schematics-scss-migrate": "^1.3.13", + "snyk": "^1.528.0", "spark-md5": "^3.0.1", "svg-crowbar": "^0.6.5", - "tree-kill": "^1.2.1", - "tslib": "^2.1.0", + "tree-kill": "^1.2.2", + "tslib": "^2.2.0", "typeface-roboto": "^1.1.13", - "xterm": "^4.9.0", + "xterm": "^4.11.0", "xterm-addon-attach": "^0.6.0", - "xterm-addon-fit": "^0.4.0", + "xterm-addon-fit": "^0.5.0", "yargs": "^16.2.0", - "zone.js": "^0.11.3" + "zone.js": "^0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "^0.1100.6", - "@angular/cli": "^11.0.6", - "@angular/compiler-cli": "^11.0.8", - "@angular/language-service": "^11.0.8", - "@sentry/cli": "^1.61.0", - "@sentry/electron": "^2.1.0", - "@types/jasmine": "~3.6.0", + "@angular-devkit/build-angular": "^0.1102.7", + "@angular/cli": "^11.2.7", + "@angular/compiler-cli": "^11.2.8", + "@angular/language-service": "^11.2.8", + "@sentry/cli": "^1.63.2", + "@sentry/electron": "^2.4.0", + "@types/jasmine": "~3.6.9", "@types/jasminewd2": "^2.0.8", - "@types/node": "14.14.10", - "codelyzer": "^6.0.0", - "electron": "^11.2.0", - "electron-builder": "22.9.1", + "@types/node": "14.14.37", + "codelyzer": "^6.0.1", + "electron": "^12.0.2", + "electron-builder": "22.10.5", "file-loader": "^6.2.0", - "jasmine-core": "~3.6.0", - "jasmine-spec-reporter": "~5.0.0", - "jquery": "^3.5.1", - "karma": "^5.2.3", + "jasmine-core": "~3.7.1", + "jasmine-spec-reporter": "~6.0.0", + "jquery": "^3.6.0", + "karma": "^6.3.2", "karma-chrome-launcher": "~3.1.0", "karma-cli": "^2.0.0", - "karma-coverage-istanbul-reporter": "~3.0.2", - "karma-jasmine": "~4.0.0", - "karma-jasmine-html-reporter": "^1.5.0", + "karma-coverage-istanbul-reporter": "~3.0.3", + "karma-jasmine": "~4.0.1", + "karma-jasmine-html-reporter": "^1.5.4", "license-checker": "^25.0.1", "popper.js": "^1.16.1", "prettier": "^2.2.1", "protractor": "^7.0.0", - "replace": "^1.2.0", + "replace": "^1.2.1", "rxjs-tslint": "^0.1.8", "ts-mockito": "^2.6.1", - "ts-node": "~9.0.0", + "ts-node": "~9.1.1", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "typescript": "4.0.2", - "webpack": "4.44.2", + "webpack": "5.31.0", "yarn-upgrade-all": "^0.5.4" }, "greenkeeper": { diff --git a/scripts/build.py b/scripts/build.py index d92591bc..4a539e4e 100644 --- a/scripts/build.py +++ b/scripts/build.py @@ -144,7 +144,7 @@ def download_from_github(name, definition, output_directory): files = [] if platform.system() == "Windows": files = definition['files']['windows'] - + for filename in files: dependency_file = os.path.join(dependency_dir, filename) dependency_url = list(filter(lambda x: x['name'] == filename, release['assets']))[0]['browser_download_url'] @@ -161,7 +161,7 @@ def download_from_http(name, definition, output_directory): files = [] if platform.system() == "Windows": files = definition['files']['windows'] - + for filename in files: dependency_file = os.path.join(dependency_dir, filename) download(url, dependency_file) @@ -193,7 +193,7 @@ def is_tagged(): return True if os.environ.get('APPVEYOR_REPO_TAG', False) in (1, "True", "true"): return True - + def is_web_ui_non_dev(): package_file = os.path.join(FILE_DIR, '..', 'package.json') @@ -237,6 +237,8 @@ def download_command(arguments): if platform.system() == "Windows": requirements = 'win-requirements.txt' + elif platform.system() == "Darwin": + requirements = 'mac-requirements.txt' else: requirements = 'requirements.txt' diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 00ed69b4..49339bb5 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,9 +1,6 @@ -setuptools==40.8.0 +setuptools==54.2.0 cx_Freeze==5.1.1 -requests==2.21.0 -packaging==19.0 -appdirs==1.4.3 -psutil==5.6.7 -jsonschema==2.6.0 # lock down jsonschema, 3.0 makes problems - -urllib3>=1.25.9 # not directly required, pinned by Snyk to avoid a vulnerability \ No newline at end of file +requests==2.25.1 +packaging==20.9 +appdirs==1.4.4 +psutil==5.8.0 diff --git a/src/ReleaseNotes.txt b/src/ReleaseNotes.txt index 61d31051..fc9bd32b 100644 --- a/src/ReleaseNotes.txt +++ b/src/ReleaseNotes.txt @@ -1,5 +1,7 @@ GNS3 WebUI is web implementation of user interface for GNS3 software. +Current version: 2.2.19 + Current version: 2020.4.0-beta.1 Bug Fixes & enhancements diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 9bd6dd11..2e95bbec 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,69 +1,59 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; - -import { ProjectMapComponent } from './components/project-map/project-map.component'; -import { ServersComponent } from './components/servers/servers.component'; -import { ProjectsComponent } from './components/projects/projects.component'; -import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component'; -import { SettingsComponent } from './components/settings/settings.component'; import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component'; -import { PreferencesComponent } from './components/preferences/preferences.component'; -import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component'; -import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component'; -import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component'; -import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component'; -import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component'; -import { VpcsPreferencesComponent } from './components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component'; -import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component'; -import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component'; -import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component'; -import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component'; -import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component'; -import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component'; -import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component'; +import { DirectLinkComponent } from './components/direct-link/direct-link.component'; +import { HelpComponent } from './components/help/help.component'; +import { ReportIssueComponent } from './components/help/report-issue/report-issue.component'; +import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component'; +import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component'; import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component'; -import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component'; -import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component'; -import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component'; -import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component'; import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component'; import { CloudNodesTemplateDetailsComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component'; -import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component'; +import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component'; +import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component'; +import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component'; +import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component'; import { EthernetSwitchesAddTemplateComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component'; import { EthernetSwitchesTemplateDetailsComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component'; -import { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component'; -import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component'; -import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component'; -import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component'; -import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component'; -import { VmwarePreferencesComponent } from './components/preferences/vmware/vmware-preferences/vmware-preferences.component'; -import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component'; -import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component'; -import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component'; -import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component'; +import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component'; import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component'; -import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component'; -import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component'; -import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component'; -import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component'; -import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component'; -import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component'; import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component'; -import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component'; -import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component'; -import { ConsoleComponent } from './components/settings/console/console.component'; -import { HelpComponent } from './components/help/help.component'; -import { TracengPreferencesComponent } from './components/preferences/traceng/traceng-preferences/traceng-preferences.component'; -import { TracengTemplatesComponent } from './components/preferences/traceng/traceng-templates/traceng-templates.component'; -import { AddTracengTemplateComponent } from './components/preferences/traceng/add-traceng/add-traceng-template.component'; -import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component'; -import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component'; +import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component'; +import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component'; +import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-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 { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component'; import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component'; -import { DirectLinkComponent } from './components/direct-link/direct-link.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 { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component'; +import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component'; +import { PreferencesComponent } from './components/preferences/preferences.component'; +import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component'; +import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.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 { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component'; +import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component'; +import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component'; +import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component'; +import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component'; +import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component'; +import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component'; +import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component'; +import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component'; +import { ProjectMapComponent } from './components/project-map/project-map.component'; +import { ProjectsComponent } from './components/projects/projects.component'; +import { ServersComponent } from './components/servers/servers.component'; +import { ConsoleComponent } from './components/settings/console/console.component'; +import { SettingsComponent } from './components/settings/settings.component'; +import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component'; import { SystemStatusComponent } from './components/system-status/system-status.component'; -import { ServerResolve } from './resolvers/server-resolve'; import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component'; import { ConsoleGuard } from './guards/console-guard'; +import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component'; +import { ServerResolve } from './resolvers/server-resolve'; const routes: Routes = [ { @@ -73,65 +63,99 @@ const routes: Routes = [ { path: '', redirectTo: 'servers', pathMatch: 'full' }, { path: 'servers', component: ServersComponent }, { path: 'bundled', component: BundledServerFinderComponent }, - { - path: 'server/:server_id/projects', + { + path: 'server/:server_id/projects', component: ProjectsComponent, - resolve: { server : ServerResolve } + resolve: { server: ServerResolve }, }, { path: 'help', component: HelpComponent }, + { path: 'help/reportissue', component: ReportIssueComponent }, { path: 'settings', component: SettingsComponent }, { path: 'settings/console', component: ConsoleComponent }, { path: 'installed-software', component: InstalledSoftwareComponent }, { path: 'server/:server_id/systemstatus', component: SystemStatusComponent }, - { path: 'server/:server_ip/:server_port/project/:project_id', component: DirectLinkComponent}, - { - path: 'server/:server_id/project/:project_id/snapshots', + { path: 'server/:server_ip/:server_port/project/:project_id', component: DirectLinkComponent }, + { + path: 'server/:server_id/project/:project_id/snapshots', component: ListOfSnapshotsComponent, - resolve: { server : ServerResolve } + resolve: { server: ServerResolve }, }, { path: 'server/:server_id/preferences', component: PreferencesComponent }, { path: 'server/:server_id/preferences/gns3vm', component: Gns3vmComponent }, // { path: 'server/:server_id/preferences/general', component: GeneralPreferencesComponent }, - { path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent}, + { path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent }, { path: 'server/:server_id/preferences/builtin/ethernet-hubs', component: EthernetHubsTemplatesComponent }, - { path: 'server/:server_id/preferences/builtin/ethernet-hubs/addtemplate', component: EthernetHubsAddTemplateComponent }, - { path: 'server/:server_id/preferences/builtin/ethernet-hubs/:template_id', component: EthernetHubsTemplateDetailsComponent }, + { + path: 'server/:server_id/preferences/builtin/ethernet-hubs/addtemplate', + component: EthernetHubsAddTemplateComponent, + }, + { + path: 'server/:server_id/preferences/builtin/ethernet-hubs/:template_id', + component: EthernetHubsTemplateDetailsComponent, + }, - { path: 'server/:server_id/preferences/builtin/ethernet-switches', component: EthernetSwitchesTemplatesComponent }, - { path: 'server/:server_id/preferences/builtin/ethernet-switches/addtemplate', component: EthernetSwitchesAddTemplateComponent }, - { path: 'server/:server_id/preferences/builtin/ethernet-switches/:template_id', component: EthernetSwitchesTemplateDetailsComponent }, + { + path: 'server/:server_id/preferences/builtin/ethernet-switches', + component: EthernetSwitchesTemplatesComponent, + }, + { + path: 'server/:server_id/preferences/builtin/ethernet-switches/addtemplate', + component: EthernetSwitchesAddTemplateComponent, + }, + { + path: 'server/:server_id/preferences/builtin/ethernet-switches/:template_id', + component: EthernetSwitchesTemplateDetailsComponent, + }, { path: 'server/:server_id/preferences/builtin/cloud-nodes', component: CloudNodesTemplatesComponent }, - { path: 'server/:server_id/preferences/builtin/cloud-nodes/addtemplate', component: CloudNodesAddTemplateComponent }, - { path: 'server/:server_id/preferences/builtin/cloud-nodes/:template_id', component: CloudNodesTemplateDetailsComponent }, + { + path: 'server/:server_id/preferences/builtin/cloud-nodes/addtemplate', + component: CloudNodesAddTemplateComponent, + }, + { + path: 'server/:server_id/preferences/builtin/cloud-nodes/:template_id', + component: CloudNodesTemplateDetailsComponent, + }, //{ path: 'server/:server_id/preferences/dynamips', component: DynamipsPreferencesComponent }, { path: 'server/:server_id/preferences/dynamips/templates', component: IosTemplatesComponent }, { path: 'server/:server_id/preferences/dynamips/templates/addtemplate', component: AddIosTemplateComponent }, { path: 'server/:server_id/preferences/dynamips/templates/:template_id', component: IosTemplateDetailsComponent }, - { path: 'server/:server_id/preferences/dynamips/templates/:template_id/copy', component: CopyIosTemplateComponent }, + { + path: 'server/:server_id/preferences/dynamips/templates/:template_id/copy', + component: CopyIosTemplateComponent, + }, // { path: 'server/:server_id/preferences/qemu', component: QemuPreferencesComponent }, { path: 'server/:server_id/preferences/qemu/templates', component: QemuVmTemplatesComponent }, - { path: 'server/:server_id/preferences/qemu/templates/:template_id/copy', component: CopyQemuVmTemplateComponent }, + { + path: 'server/:server_id/preferences/qemu/templates/:template_id/copy', + component: CopyQemuVmTemplateComponent, + }, { path: 'server/:server_id/preferences/qemu/templates/:template_id', component: QemuVmTemplateDetailsComponent }, { path: 'server/:server_id/preferences/qemu/addtemplate', component: AddQemuVmTemplateComponent }, // { path: 'server/:server_id/preferences/vpcs', component: VpcsPreferencesComponent }, { path: 'server/:server_id/preferences/vpcs/templates', component: VpcsTemplatesComponent }, - { path: 'server/:server_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent}, + { path: 'server/:server_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent }, { path: 'server/:server_id/preferences/vpcs/addtemplate', component: AddVpcsTemplateComponent }, // { path: 'server/:server_id/preferences/virtualbox', component: VirtualBoxPreferencesComponent }, { path: 'server/:server_id/preferences/virtualbox/templates', component: VirtualBoxTemplatesComponent }, - { path: 'server/:server_id/preferences/virtualbox/templates/:template_id', component: VirtualBoxTemplateDetailsComponent }, + { + path: 'server/:server_id/preferences/virtualbox/templates/:template_id', + component: VirtualBoxTemplateDetailsComponent, + }, { path: 'server/:server_id/preferences/virtualbox/addtemplate', component: AddVirtualBoxTemplateComponent }, // { path: 'server/:server_id/preferences/vmware', component: VmwarePreferencesComponent }, { path: 'server/:server_id/preferences/vmware/templates', component: VmwareTemplatesComponent }, - { path: 'server/:server_id/preferences/vmware/templates/:template_id', component: VmwareTemplateDetailsComponent }, + { + path: 'server/:server_id/preferences/vmware/templates/:template_id', + component: VmwareTemplateDetailsComponent, + }, { path: 'server/:server_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent }, // { path: 'server/:server_id/preferences/traceng', component: TracengPreferencesComponent }, @@ -140,37 +164,49 @@ const routes: Routes = [ // { path: 'server/:server_id/preferences/traceng/addtemplate', component: AddTracengTemplateComponent }, { path: 'server/:server_id/preferences/docker/templates', component: DockerTemplatesComponent }, - { path: 'server/:server_id/preferences/docker/templates/:template_id', component: DockerTemplateDetailsComponent }, - { path: 'server/:server_id/preferences/docker/templates/:template_id/copy', component: CopyDockerTemplateComponent }, + { + path: 'server/:server_id/preferences/docker/templates/:template_id', + component: DockerTemplateDetailsComponent, + }, + { + path: 'server/:server_id/preferences/docker/templates/:template_id/copy', + component: CopyDockerTemplateComponent, + }, { 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: 'server/:server_id/preferences/iou/addtemplate', component: AddIouTemplateComponent }, + ], }, - { - path: 'server/:server_id/project/:project_id', + { + path: 'server/:server_id/project/:project_id', component: ProjectMapComponent, - canDeactivate: [ConsoleGuard] + canDeactivate: [ConsoleGuard], }, - { - path: 'server/:server_id/project/:project_id/nodes/:node_id', - component: WebConsoleFullWindowComponent + { + path: 'server/:server_id/project/:project_id/nodes/:node_id', + component: WebConsoleFullWindowComponent, }, - { - path: 'static/web-ui/server/:server_id/project/:project_id/nodes/:node_id', - component: WebConsoleFullWindowComponent + { + path: 'static/web-ui/server/:server_id/project/:project_id/nodes/:node_id', + component: WebConsoleFullWindowComponent, }, { path: '**', - component: PageNotFoundComponent - } + component: PageNotFoundComponent, + }, ]; @NgModule({ - imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled', enableTracing: false, scrollPositionRestoration: 'enabled'})], - exports: [RouterModule] + imports: [ + RouterModule.forRoot(routes, { + anchorScrolling: 'enabled', + enableTracing: false, + scrollPositionRestoration: 'enabled', + }), + ], + exports: [RouterModule], }) export class AppRoutingModule {} diff --git a/src/app/app.component.html b/src/app/app.component.html index cc3b2bf2..db17fd83 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,2 +1,4 @@ - - +
+ + +
diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 1bc4310f..193c4c31 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,3 +1,11 @@ mat-menu-panel { - min-height: 0px; + min-height: 0px; +} + +.dark { + background: #263238 !important; +} + +.light { + background: white !important; } diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 1eb4a588..388f4ac6 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,14 +1,14 @@ -import { TestBed, async, ComponentFixture } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { AppComponent } from './app.component'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatIconModule } from '@angular/material/icon'; -import { SettingsService } from './services/settings.service'; +import { RouterTestingModule } from '@angular/router/testing'; import { PersistenceService } from 'angular-persistence'; import { ElectronService, NgxElectronModule } from 'ngx-electron'; -import createSpyObj = jasmine.createSpyObj; -import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { AppComponent } from './app.component'; import { ProgressService } from './common/progress/progress.service'; +import { SettingsService } from './services/settings.service'; + +import createSpyObj = jasmine.createSpyObj; // import 'jasmine'; describe('AppComponent', () => { @@ -22,7 +22,7 @@ describe('AppComponent', () => { declarations: [AppComponent], imports: [RouterTestingModule, MatIconModule, NgxElectronModule], providers: [SettingsService, PersistenceService, ProgressService], - schemas: [NO_ERRORS_SCHEMA] + schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); electronService = TestBed.get(ElectronService); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 401e4efa..e9e5233a 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,19 +1,23 @@ -import { Component, OnInit } from '@angular/core'; +import { OverlayContainer } from '@angular/cdk/overlay'; +import { Component, HostBinding, OnInit } from '@angular/core'; import { MatIconRegistry } from '@angular/material/icon'; import { DomSanitizer } from '@angular/platform-browser'; +import { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router'; import { ElectronService } from 'ngx-electron'; +import { ProgressService } from './common/progress/progress.service'; import { SettingsService } from './services/settings.service'; import { ThemeService } from './services/theme.service'; -import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router'; -import { ProgressService } from './common/progress/progress.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'] + styleUrls: ['./app.component.scss'], }) export class AppComponent implements OnInit { + public darkThemeEnabled: boolean = false; + constructor( + private overlayContainer: OverlayContainer, iconReg: MatIconRegistry, sanitizer: DomSanitizer, private settingsService: SettingsService, @@ -30,28 +34,39 @@ export class AppComponent implements OnInit { }); } + @HostBinding('class') componentCssClass; + ngOnInit(): void { if (this.electronService.isElectronApp) { - this.settingsService.subscribe(settings => { + this.settingsService.subscribe((settings) => { this.electronService.ipcRenderer.send('settings.changed', settings); }); } - let theme = localStorage.getItem('theme'); - if (theme === 'light') { - this.themeService.setDarkMode(false); - } else { - this.themeService.setDarkMode(true); - } + + this.applyTheme(this.themeService.savedTheme + '-theme'); + this.themeService.themeChanged.subscribe((event: string) => { + this.applyTheme(event); + }); } - checkEvent(routerEvent) : void { + applyTheme(theme: string) { + if (theme === 'dark-theme') { + this.darkThemeEnabled = true; + } else { + this.darkThemeEnabled = false; + } + this.overlayContainer.getContainerElement().classList.add(theme); + this.componentCssClass = theme; + } + + checkEvent(routerEvent): void { if (routerEvent instanceof NavigationStart) { this.progressService.activate(); - } - - else if (routerEvent instanceof NavigationEnd || - routerEvent instanceof NavigationCancel || - routerEvent instanceof NavigationError) { + } else if ( + routerEvent instanceof NavigationEnd || + routerEvent instanceof NavigationCancel || + routerEvent instanceof NavigationError + ) { this.progressService.deactivate(); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5379db9c..774358cc 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,291 +1,280 @@ -import { BrowserModule, Title } from '@angular/platform-browser'; -import { NgModule, ErrorHandler } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { AngularReactBrowserModule } from '@angular-react/core'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { OverlayModule } from '@angular/cdk/overlay'; import { CdkTableModule } from '@angular/cdk/table'; import { HttpClientModule } from '@angular/common/http'; - +import { ErrorHandler, NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { BrowserModule, Title } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -import { D3Service } from 'd3-ng2-service'; +import { DragAndDropModule } from 'angular-draggable-droppable'; import { PersistenceModule } from 'angular-persistence'; -import { NgxElectronModule } from 'ngx-electron'; +import { ResizableModule } from 'angular-resizable-element'; +import { D3Service } from 'd3-ng2-service'; +import { NgCircleProgressModule } from 'ng-circle-progress'; import { FileUploadModule } from 'ng2-file-upload'; +import { NgxChildProcessModule } from 'ngx-childprocess'; +import { NgxElectronModule } from 'ngx-electron'; import { AppRoutingModule } from './app-routing.module'; - -import { VersionService } from './services/version.service'; -import { ProjectService } from './services/project.service'; -import { SymbolService } from './services/symbol.service'; -import { ServerService } from './services/server.service'; -import { IndexedDbService } from './services/indexed-db.service'; -import { HttpServer, ServerErrorHandler } from './services/http-server.service'; -import { SnapshotService } from './services/snapshot.service'; -import { ProgressDialogService } from './common/progress-dialog/progress-dialog.service'; -import { NodeService } from './services/node.service'; -import { TemplateService } from './services/template.service'; -import { LinkService } from './services/link.service'; - -import { ProjectsComponent } from './components/projects/projects.component'; -import { AddBlankProjectDialogComponent } from './components/projects/add-blank-project-dialog/add-blank-project-dialog.component'; -import { ImportProjectDialogComponent } from './components/projects/import-project-dialog/import-project-dialog.component'; -import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-dialog.component'; -import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component'; -import { ProgressDialogComponent } from './common/progress-dialog/progress-dialog.component'; import { AppComponent } from './app.component'; - -import { ProjectMapComponent } from './components/project-map/project-map.component'; -import { ServersComponent } from './components/servers/servers.component'; -import { AddServerDialogComponent } from './components/servers/add-server-dialog/add-server-dialog.component'; -import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component'; -import { ContextConsoleMenuComponent } from './components/project-map/context-console-menu/context-console-menu.component'; -import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component'; -import { StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component'; -import { TemplateComponent } from './components/template/template.component'; -import { TemplateListDialogComponent } from './components/template/template-list-dialog/template-list-dialog.component'; import { CartographyModule } from './cartography/cartography.module'; -import { ToasterService } from './services/toaster.service'; -import { ProjectWebServiceHandler } from './handlers/project-web-service-handler'; +import { DrawingsDataSource } from './cartography/datasources/drawings-datasource'; import { LinksDataSource } from './cartography/datasources/links-datasource'; import { NodesDataSource } from './cartography/datasources/nodes-datasource'; import { SymbolsDataSource } from './cartography/datasources/symbols-datasource'; -import { SelectionManager } from './cartography/managers/selection-manager'; import { InRectangleHelper } from './cartography/helpers/in-rectangle-helper'; -import { DrawingsDataSource } from './cartography/datasources/drawings-datasource'; -import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component'; -import { MoveLayerDownActionComponent } from './components/project-map/context-menu/actions/move-layer-down-action/move-layer-down-action.component'; -import { MoveLayerUpActionComponent } from './components/project-map/context-menu/actions/move-layer-up-action/move-layer-up-action.component'; -import { SettingsComponent } from './components/settings/settings.component'; -import { SettingsService } from './services/settings.service'; - -import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component'; +import { SelectionManager } from './cartography/managers/selection-manager'; +import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler'; +import { ProgressDialogComponent } from './common/progress-dialog/progress-dialog.component'; +import { ProgressDialogService } from './common/progress-dialog/progress-dialog.service'; import { ProgressComponent } from './common/progress/progress.component'; import { ProgressService } from './common/progress/progress.service'; -import { version } from './version'; -import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler'; -import { environment } from '../environments/environment'; -import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component'; -import { ServerDatabase } from './services/server.database'; -import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component'; -import { SnapshotMenuItemComponent } from './components/snapshots/snapshot-menu-item/snapshot-menu-item.component'; -import { MATERIAL_IMPORTS } from './material.imports'; -import { DrawingService } from './services/drawing.service'; -import { ProjectNameValidator } from './components/projects/models/projectNameValidator'; -import { MatSidenavModule } from '@angular/material/sidenav'; -import { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component'; -import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component'; - -import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component'; +import { AdbutlerComponent } from './components/adbutler/adbutler.component'; +import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component'; +import { InformationDialogComponent } from './components/dialogs/information-dialog.component'; +import { DirectLinkComponent } from './components/direct-link/direct-link.component'; +import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component'; +import { DrawingDraggedComponent } from './components/drawings-listeners/drawing-dragged/drawing-dragged.component'; import { DrawingResizedComponent } from './components/drawings-listeners/drawing-resized/drawing-resized.component'; -import { TextEditedComponent } from './components/drawings-listeners/text-edited/text-edited.component'; +import { InterfaceLabelDraggedComponent } from './components/drawings-listeners/interface-label-dragged/interface-label-dragged.component'; +import { LinkCreatedComponent } from './components/drawings-listeners/link-created/link-created.component'; import { NodeDraggedComponent } from './components/drawings-listeners/node-dragged/node-dragged.component'; import { NodeLabelDraggedComponent } from './components/drawings-listeners/node-label-dragged/node-label-dragged.component'; -import { DrawingDraggedComponent } from './components/drawings-listeners/drawing-dragged/drawing-dragged.component'; -import { LinkCreatedComponent } from './components/drawings-listeners/link-created/link-created.component'; -import { InterfaceLabelDraggedComponent } from './components/drawings-listeners/interface-label-dragged/interface-label-dragged.component'; -import { ToolsService } from './services/tools.service'; import { TextAddedComponent } from './components/drawings-listeners/text-added/text-added.component'; -import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component'; +import { TextEditedComponent } from './components/drawings-listeners/text-edited/text-edited.component'; +import { HelpComponent } from './components/help/help.component'; +import { ReportIssueComponent } from './components/help/report-issue/report-issue.component'; import { InstallSoftwareComponent } from './components/installed-software/install-software/install-software.component'; - -import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component'; -import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component'; -import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component'; -import { PreferencesComponent } from './components/preferences/preferences.component'; -import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component'; -import { ServerSettingsService } from './services/server-settings.service'; -import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component'; -import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component'; -import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component'; -import { QemuService } from './services/qemu.service'; -import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component'; -import { VpcsPreferencesComponent } from './components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component'; -import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component'; -import { VpcsService } from './services/vpcs.service'; -import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component'; -import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component'; -import { TemplateMocksService } from './services/template-mocks.service'; -import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component'; -import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component'; -import { VirtualBoxService } from './services/virtual-box.service'; -import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component'; -import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component'; +import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component'; +import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component'; import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component'; -import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component'; -import { BuiltInTemplatesService } from './services/built-in-templates.service'; -import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component'; -import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component'; -import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component'; import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component'; import { CloudNodesTemplateDetailsComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component'; -import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component'; +import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component'; +import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component'; +import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component'; +import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component'; import { EthernetSwitchesAddTemplateComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component'; import { EthernetSwitchesTemplateDetailsComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component'; -import { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component'; -import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component'; -import { IosService } from './services/ios.service'; -import { SymbolsComponent } from './components/preferences/common/symbols/symbols.component'; -import { InstalledSoftwareService } from './services/installed-software.service'; -import { ExternalSoftwareDefinitionService } from './services/external-software-definition.service'; -import { PlatformService } from './services/platform.service'; -import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component'; -import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component'; -import { IosConfigurationService } from './services/ios-configuration.service'; -import { QemuConfigurationService } from './services/qemu-configuration.service'; -import { VirtualBoxConfigurationService } from './services/virtual-box-configuration.service'; -import { VpcsConfigurationService } from './services/vpcs-configuration.service'; -import { BuiltInTemplatesConfigurationService } from './services/built-in-templates-configuration.service'; -import { VmwarePreferencesComponent } from './components/preferences/vmware/vmware-preferences/vmware-preferences.component'; -import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component'; -import { VmwareService } from './services/vmware.service'; -import { VmwareConfigurationService } from './services/vmware-configuration.service'; -import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component'; -import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component'; +import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component'; +import { CustomAdaptersTableComponent } from './components/preferences/common/custom-adapters-table/custom-adapters-table.component'; +import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component'; import { DeleteConfirmationDialogComponent } from './components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component'; import { DeleteTemplateComponent } from './components/preferences/common/delete-template-component/delete-template.component'; -import { DockerService } from './services/docker.service'; -import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component'; -import { DockerConfigurationService } from './services/docker-configuration.service'; -import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component'; -import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component'; -import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component'; -import { IouService } from './services/iou.service'; -import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component'; -import { IouConfigurationService } from './services/iou-configuration.service'; -import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component'; -import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component'; -import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component'; -import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component'; -import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component'; import { EmptyTemplatesListComponent } from './components/preferences/common/empty-templates-list/empty-templates-list.component'; -import { SymbolsMenuComponent } from './components/preferences/common/symbols-menu/symbols-menu.component'; -import { SearchFilter } from './filters/searchFilter.pipe'; -import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service'; -import { ServerManagementService } from './services/server-management.service'; -import { DeleteActionComponent } from './components/project-map/context-menu/actions/delete-action/delete-action.component'; -import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component'; -import { DateFilter } from './filters/dateFilter.pipe'; -import { NameFilter } from './filters/nameFilter.pipe'; -import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component'; - -import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component'; -import { ConsoleComponent } from './components/settings/console/console.component'; -import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component'; -import { PacketFiltersActionComponent } from './components/project-map/context-menu/actions/packet-filters-action/packet-filters-action.component'; -import { PacketFiltersDialogComponent } from './components/project-map/packet-capturing/packet-filters/packet-filters.component'; -import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component'; -import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component'; -import { StartCaptureDialogComponent } from './components/project-map/packet-capturing/start-capture/start-capture.component'; -import { SuspendLinkActionComponent } from './components/project-map/context-menu/actions/suspend-link/suspend-link-action.component'; -import { ResumeLinkActionComponent } from './components/project-map/context-menu/actions/resume-link-action/resume-link-action.component'; -import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component'; -import { MapScaleService } from './services/mapScale.service'; -import { AdbutlerComponent } from './components/adbutler/adbutler.component'; -import { ConsoleService } from './services/settings/console.service'; -import { DefaultConsoleService } from './services/settings/default-console.service'; -import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer'; -import { NotificationBoxComponent } from './components/notification-box/notification-box.component'; -import { NonNegativeValidator } from './validators/non-negative-validator'; -import { RotationValidator } from './validators/rotation-validator'; -import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component'; -import { MapSettingsService } from './services/mapsettings.service'; -import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component'; -import { HelpComponent } from './components/help/help.component'; -import { ConfigEditorDialogComponent } from './components/project-map/node-editors/config-editor/config-editor.component'; -import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component'; -import { LogConsoleComponent } from './components/project-map/log-console/log-console.component'; -import { LogEventsDataSource } from './components/project-map/log-console/log-events-datasource'; -import { SaveProjectDialogComponent } from './components/projects/save-project-dialog/save-project-dialog.component'; -import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component'; -import { ShowNodeActionComponent } from './components/project-map/context-menu/actions/show-node-action/show-node-action.component'; -import { InfoDialogComponent } from './components/project-map/info-dialog/info-dialog.component'; -import { InfoService } from './services/info.service'; -import { BringToFrontActionComponent } from './components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component'; -import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component'; -import { ImportConfigActionComponent } from './components/project-map/context-menu/actions/import-config/import-config-action.component'; -import { ConsoleDeviceActionBrowserComponent } from './components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component'; -import { ChangeSymbolDialogComponent } from './components/project-map/change-symbol-dialog/change-symbol-dialog.component'; -import { ChangeSymbolActionComponent } from './components/project-map/context-menu/actions/change-symbol/change-symbol-action.component'; -import { EditProjectDialogComponent } from './components/projects/edit-project-dialog/edit-project-dialog.component'; -import { ProjectsFilter } from './filters/projectsFilter.pipe'; -import { ComputeService } from './services/compute.service'; -import { ReloadNodeActionComponent } from './components/project-map/context-menu/actions/reload-node-action/reload-node-action.component'; -import { SuspendNodeActionComponent } from './components/project-map/context-menu/actions/suspend-node-action/suspend-node-action.component'; -import { ConfigActionComponent } from './components/project-map/context-menu/actions/config-action/config-action.component'; -import { ConfiguratorDialogVpcsComponent } from './components/project-map/node-editors/configurator/vpcs/configurator-vpcs.component'; -import { ConfiguratorDialogEthernetHubComponent } from './components/project-map/node-editors/configurator/ethernet_hub/configurator-ethernet-hub.component'; -import { ConfiguratorDialogEthernetSwitchComponent } from './components/project-map/node-editors/configurator/ethernet-switch/configurator-ethernet-switch.component'; import { PortsComponent } from './components/preferences/common/ports/ports.component'; -import { ConfiguratorDialogSwitchComponent } from './components/project-map/node-editors/configurator/switch/configurator-switch.component'; -import { ConfiguratorDialogVirtualBoxComponent } from './components/project-map/node-editors/configurator/virtualbox/configurator-virtualbox.component'; -import { CustomAdaptersTableComponent } from './components/preferences/common/custom-adapters-table/custom-adapters-table.component'; -import { ConfiguratorDialogQemuComponent } from './components/project-map/node-editors/configurator/qemu/configurator-qemu.component'; -import { ConfiguratorDialogCloudComponent } from './components/project-map/node-editors/configurator/cloud/configurator-cloud.component'; +import { SymbolsMenuComponent } from './components/preferences/common/symbols-menu/symbols-menu.component'; +import { SymbolsComponent } from './components/preferences/common/symbols/symbols.component'; import { UdpTunnelsComponent } from './components/preferences/common/udp-tunnels/udp-tunnels.component'; -import { ConfiguratorDialogAtmSwitchComponent } from './components/project-map/node-editors/configurator/atm_switch/configurator-atm-switch.component'; -import { ConfiguratorDialogVmwareComponent } from './components/project-map/node-editors/configurator/vmware/configurator-vmware.component'; -import { ConfiguratorDialogIouComponent } from './components/project-map/node-editors/configurator/iou/configurator-iou.component'; -import { ConfiguratorDialogIosComponent } from './components/project-map/node-editors/configurator/ios/configurator-ios.component'; -import { ConfiguratorDialogDockerComponent } from './components/project-map/node-editors/configurator/docker/configurator-docker.component'; -import { EditNetworkConfigurationDialogComponent } from './components/project-map/node-editors/configurator/docker/edit-network-configuration/edit-network-configuration.component'; -import { ConfigureCustomAdaptersDialogComponent } from './components/project-map/node-editors/configurator/docker/configure-custom-adapters/configure-custom-adapters.component'; -import { ConfiguratorDialogNatComponent } from './components/project-map/node-editors/configurator/nat/configurator-nat.component'; -import { ConfiguratorDialogTracengComponent } from './components/project-map/node-editors/configurator/traceng/configurator-traceng.component'; +import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component'; +import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component'; +import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component'; +import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component'; +import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component'; +import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component'; +import { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.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 { 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 { 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 { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component'; +import { PreferencesComponent } from './components/preferences/preferences.component'; +import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component'; +import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.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 { 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 { TracengTemplatesComponent } from './components/preferences/traceng/traceng-templates/traceng-templates.component'; -import { TracengService } from './services/traceng.service'; import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component'; -import { QemuImageCreatorComponent } from './components/project-map/node-editors/configurator/qemu/qemu-image-creator/qemu-image-creator.component'; -import { ChooseNameDialogComponent } from './components/projects/choose-name-dialog/choose-name-dialog.component'; -import { PacketCaptureService } from './services/packet-capture.service'; -import { StartCaptureOnStartedLinkActionComponent } from './components/project-map/context-menu/actions/start-capture-on-started-link/start-capture-on-started-link.component'; -import { LockActionComponent } from './components/project-map/context-menu/actions/lock-action/lock-action.component'; -import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component'; -import { ScreenshotDialogComponent } from './components/project-map/screenshot-dialog/screenshot-dialog.component'; -import { ResizableModule } from 'angular-resizable-element'; -import { DragAndDropModule } from 'angular-draggable-droppable'; -import { DragDropModule } from '@angular/cdk/drag-drop'; -import { PageNotFoundComponent } from './components/page-not-found/page-not-found.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 { 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 { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component'; +import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component'; +import { VmwarePreferencesComponent } from './components/preferences/vmware/vmware-preferences/vmware-preferences.component'; +import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component'; +import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component'; +import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component'; +import { VpcsPreferencesComponent } from './components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component'; +import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component'; +import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component'; +import { ChangeHostnameDialogComponent } from './components/project-map/change-hostname-dialog/change-hostname-dialog.component'; +import { ChangeSymbolDialogComponent } from './components/project-map/change-symbol-dialog/change-symbol-dialog.component'; +import { ConsoleWrapperComponent } from './components/project-map/console-wrapper/console-wrapper.component'; +import { ContextConsoleMenuComponent } from './components/project-map/context-console-menu/context-console-menu.component'; import { AlignHorizontallyActionComponent } from './components/project-map/context-menu/actions/align-horizontally/align-horizontally.component'; import { AlignVerticallyActionComponent } from './components/project-map/context-menu/actions/align_vertically/align-vertically.component'; -import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component'; -import { TemplateFilter } from './filters/templateFilter.pipe'; -import { NotificationService } from './services/notification.service'; -import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component'; -import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component'; -import { Gns3vmService } from './services/gns3vm.service'; -import { ThemeService } from './services/theme.service'; -import { ConfigureGns3VMDialogComponent } from './components/servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component'; -import { ImportApplianceComponent } from './components/project-map/import-appliance/import-appliance.component'; -import { GoogleAnalyticsService } from './services/google-analytics.service'; -import { DirectLinkComponent } from './components/direct-link/direct-link.component'; -import { SystemStatusComponent } from './components/system-status/system-status.component'; -import { StatusInfoComponent } from './components/system-status/status-info/status-info.component'; -import { StatusChartComponent } from './components/system-status/status-chart/status-chart.component'; -import { NgCircleProgressModule } from 'ng-circle-progress'; -import { OpenFileExplorerActionComponent } from './components/project-map/context-menu/actions/open-file-explorer/open-file-explorer-action.component'; -import { NgxChildProcessModule } from 'ngx-childprocess'; -import { ServerResolve } from './resolvers/server-resolve'; -import { HttpConsoleActionComponent } from './components/project-map/context-menu/actions/http-console/http-console-action.component'; -import { WebConsoleComponent } from './components/project-map/web-console/web-console.component'; -import { ConsoleWrapperComponent } from './components/project-map/console-wrapper/console-wrapper.component'; -import { NodeConsoleService } from './services/nodeConsole.service'; -import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component'; -import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component'; -import { ConsoleGuard } from './guards/console-guard'; -import { NewTemplateDialogComponent } from './components/project-map/new-template-dialog/new-template-dialog.component'; -import { ApplianceService } from './services/appliances.service'; -import { DataSourceFilter } from './filters/dataSourceFilter'; +import { BringToFrontActionComponent } from './components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component'; import { ChangeHostnameActionComponent } from './components/project-map/context-menu/actions/change-hostname/change-hostname-action.component'; -import { ChangeHostnameDialogComponent } from './components/project-map/change-hostname-dialog/change-hostname-dialog.component'; +import { ChangeSymbolActionComponent } from './components/project-map/context-menu/actions/change-symbol/change-symbol-action.component'; +import { ConfigActionComponent } from './components/project-map/context-menu/actions/config-action/config-action.component'; +import { ConsoleDeviceActionBrowserComponent } from './components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component'; +import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component'; +import { DeleteActionComponent } from './components/project-map/context-menu/actions/delete-action/delete-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 { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-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 { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component'; +import { HttpConsoleActionComponent } from './components/project-map/context-menu/actions/http-console/http-console-action.component'; +import { ImportConfigActionComponent } from './components/project-map/context-menu/actions/import-config/import-config-action.component'; +import { LockActionComponent } from './components/project-map/context-menu/actions/lock-action/lock-action.component'; +import { MoveLayerDownActionComponent } from './components/project-map/context-menu/actions/move-layer-down-action/move-layer-down-action.component'; +import { MoveLayerUpActionComponent } from './components/project-map/context-menu/actions/move-layer-up-action/move-layer-up-action.component'; +import { OpenFileExplorerActionComponent } from './components/project-map/context-menu/actions/open-file-explorer/open-file-explorer-action.component'; +import { PacketFiltersActionComponent } from './components/project-map/context-menu/actions/packet-filters-action/packet-filters-action.component'; +import { ReloadNodeActionComponent } from './components/project-map/context-menu/actions/reload-node-action/reload-node-action.component'; +import { ResumeLinkActionComponent } from './components/project-map/context-menu/actions/resume-link-action/resume-link-action.component'; +import { ShowNodeActionComponent } from './components/project-map/context-menu/actions/show-node-action/show-node-action.component'; +import { StartCaptureOnStartedLinkActionComponent } from './components/project-map/context-menu/actions/start-capture-on-started-link/start-capture-on-started-link.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 { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-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 { 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 { 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 { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-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 { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer'; +import { ImportApplianceComponent } from './components/project-map/import-appliance/import-appliance.component'; +import { InfoDialogComponent } from './components/project-map/info-dialog/info-dialog.component'; +import { LogConsoleComponent } from './components/project-map/log-console/log-console.component'; +import { LogEventsDataSource } from './components/project-map/log-console/log-events-datasource'; import { ApplianceInfoDialogComponent } from './components/project-map/new-template-dialog/appliance-info-dialog/appliance-info-dialog.component'; -import { ResetLinkActionComponent } from './components/project-map/context-menu/actions/reset-link/reset-link-action.component'; -import { ReadmeEditorComponent } from './components/projects/edit-project-dialog/readme-editor/readme-editor.component'; -import { MarkedDirective } from './directives/marked.directive'; -import { InformationDialogComponent } from './components/dialogs/information-dialog.component'; +import { NewTemplateDialogComponent } from './components/project-map/new-template-dialog/new-template-dialog.component'; import { TemplateNameDialogComponent } from './components/project-map/new-template-dialog/template-name-dialog/template-name-dialog.component'; -import { UpdatesService } from './services/updates.service'; +import { ConfigEditorDialogComponent } from './components/project-map/node-editors/config-editor/config-editor.component'; +import { ConfiguratorDialogAtmSwitchComponent } from './components/project-map/node-editors/configurator/atm_switch/configurator-atm-switch.component'; +import { ConfiguratorDialogCloudComponent } from './components/project-map/node-editors/configurator/cloud/configurator-cloud.component'; +import { ConfiguratorDialogDockerComponent } from './components/project-map/node-editors/configurator/docker/configurator-docker.component'; +import { ConfigureCustomAdaptersDialogComponent } from './components/project-map/node-editors/configurator/docker/configure-custom-adapters/configure-custom-adapters.component'; +import { EditNetworkConfigurationDialogComponent } from './components/project-map/node-editors/configurator/docker/edit-network-configuration/edit-network-configuration.component'; +import { ConfiguratorDialogEthernetSwitchComponent } from './components/project-map/node-editors/configurator/ethernet-switch/configurator-ethernet-switch.component'; +import { ConfiguratorDialogEthernetHubComponent } from './components/project-map/node-editors/configurator/ethernet_hub/configurator-ethernet-hub.component'; +import { ConfiguratorDialogIosComponent } from './components/project-map/node-editors/configurator/ios/configurator-ios.component'; +import { ConfiguratorDialogIouComponent } from './components/project-map/node-editors/configurator/iou/configurator-iou.component'; +import { ConfiguratorDialogNatComponent } from './components/project-map/node-editors/configurator/nat/configurator-nat.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 { 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 { 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 { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component'; +import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component'; +import { PacketFiltersDialogComponent } from './components/project-map/packet-capturing/packet-filters/packet-filters.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 { 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 { 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 { ChooseNameDialogComponent } from './components/projects/choose-name-dialog/choose-name-dialog.component'; +import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component'; +import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-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 { ProjectNameValidator } from './components/projects/models/projectNameValidator'; +import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component'; +import { ProjectsComponent } from './components/projects/projects.component'; +import { SaveProjectDialogComponent } from './components/projects/save-project-dialog/save-project-dialog.component'; +import { AddServerDialogComponent } from './components/servers/add-server-dialog/add-server-dialog.component'; +import { ConfigureGns3VMDialogComponent } from './components/servers/configure-gns3vm-dialog/configure-gns3vm-dialog.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 { SettingsComponent } from './components/settings/settings.component'; +import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component'; +import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component'; +import { SnapshotMenuItemComponent } from './components/snapshots/snapshot-menu-item/snapshot-menu-item.component'; +import { StatusChartComponent } from './components/system-status/status-chart/status-chart.component'; +import { StatusInfoComponent } from './components/system-status/status-info/status-info.component'; +import { SystemStatusComponent } from './components/system-status/system-status.component'; +import { TemplateListDialogComponent } from './components/template/template-list-dialog/template-list-dialog.component'; +import { TemplateComponent } from './components/template/template.component'; +import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component'; +import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component'; +import { DataSourceFilter } from './filters/dataSourceFilter'; +import { DateFilter } from './filters/dateFilter.pipe'; +import { NameFilter } from './filters/nameFilter.pipe'; +import { ProjectsFilter } from './filters/projectsFilter.pipe'; +import { SearchFilter } from './filters/searchFilter.pipe'; +import { TemplateFilter } from './filters/templateFilter.pipe'; +import { ConsoleGuard } from './guards/console-guard'; +import { ProjectWebServiceHandler } from './handlers/project-web-service-handler'; +import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component'; +import { MATERIAL_IMPORTS } from './material.imports'; +import { ServerResolve } from './resolvers/server-resolve'; +import { ApplianceService } from './services/appliances.service'; +import { BuiltInTemplatesConfigurationService } from './services/built-in-templates-configuration.service'; +import { BuiltInTemplatesService } from './services/built-in-templates.service'; +import { ComputeService } from './services/compute.service'; +import { DockerConfigurationService } from './services/docker-configuration.service'; +import { DockerService } from './services/docker.service'; +import { DrawingService } from './services/drawing.service'; +import { ExternalSoftwareDefinitionService } from './services/external-software-definition.service'; +import { Gns3vmService } from './services/gns3vm.service'; +import { GoogleAnalyticsService } from './services/google-analytics.service'; +import { HttpServer, ServerErrorHandler } from './services/http-server.service'; +import { IndexedDbService } from './services/indexed-db.service'; +import { InfoService } from './services/info.service'; +import { InstalledSoftwareService } from './services/installed-software.service'; +import { IosConfigurationService } from './services/ios-configuration.service'; +import { IosService } from './services/ios.service'; +import { IouConfigurationService } from './services/iou-configuration.service'; +import { IouService } from './services/iou.service'; +import { LinkService } from './services/link.service'; +import { MapScaleService } from './services/mapScale.service'; +import { MapSettingsService } from './services/mapsettings.service'; +import { NodeService } from './services/node.service'; +import { NodeConsoleService } from './services/nodeConsole.service'; +import { NotificationService } from './services/notification.service'; +import { PacketCaptureService } from './services/packet-capture.service'; +import { PlatformService } from './services/platform.service'; +import { ProjectService } from './services/project.service'; +import { QemuConfigurationService } from './services/qemu-configuration.service'; +import { QemuService } from './services/qemu.service'; +import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service'; +import { ServerManagementService } from './services/server-management.service'; +import { ServerSettingsService } from './services/server-settings.service'; +import { ServerDatabase } from './services/server.database'; +import { ServerService } from './services/server.service'; +import { SettingsService } from './services/settings.service'; +import { ConsoleService } from './services/settings/console.service'; +import { DefaultConsoleService } from './services/settings/default-console.service'; +import { SnapshotService } from './services/snapshot.service'; +import { SymbolService } from './services/symbol.service'; +import { TemplateMocksService } from './services/template-mocks.service'; +import { TemplateService } from './services/template.service'; +import { ThemeService } from './services/theme.service'; +import { ToasterService } from './services/toaster.service'; +import { ToolsService } from './services/tools.service'; +import { TracengService } from './services/traceng.service'; +import { UpdatesService } from './services/updates.service'; +import { VersionService } from './services/version.service'; +import { VirtualBoxConfigurationService } from './services/virtual-box-configuration.service'; +import { VirtualBoxService } from './services/virtual-box.service'; +import { VmwareConfigurationService } from './services/vmware-configuration.service'; +import { VmwareService } from './services/vmware.service'; +import { VpcsConfigurationService } from './services/vpcs-configuration.service'; +import { VpcsService } from './services/vpcs.service'; +import { NonNegativeValidator } from './validators/non-negative-validator'; +import { RotationValidator } from './validators/rotation-validator'; +import { MarkedDirective } from './directives/marked.directive'; @NgModule({ declarations: [ @@ -318,7 +307,6 @@ import { ProjectReadmeComponent } from './components/project-map/project-readme/ StopCaptureActionComponent, ResumeLinkActionComponent, SuspendLinkActionComponent, - ResetLinkActionComponent, SettingsComponent, PreferencesComponent, BundledServerFinderComponent, @@ -402,7 +390,6 @@ import { ProjectReadmeComponent } from './components/project-map/project-readme/ ShowNodeActionComponent, ConsoleComponent, NodesMenuComponent, - NotificationBoxComponent, ProjectMapMenuComponent, HelpComponent, ConfigEditorDialogComponent, @@ -475,9 +462,11 @@ import { ProjectReadmeComponent } from './components/project-map/project-readme/ InformationDialogComponent, TemplateNameDialogComponent, ConfigureCustomAdaptersDialogComponent, - EditNetworkConfigurationDialogComponent + EditNetworkConfigurationDialogComponent, + ReportIssueComponent, ], imports: [ + AngularReactBrowserModule, BrowserModule, HttpClientModule, AppRoutingModule, @@ -495,7 +484,8 @@ import { ProjectReadmeComponent } from './components/project-map/project-readme/ DragDropModule, NgxChildProcessModule, MATERIAL_IMPORTS, - NgCircleProgressModule.forRoot() + NgCircleProgressModule.forRoot(), + OverlayModule, ], providers: [ SettingsService, @@ -570,7 +560,7 @@ import { ProjectReadmeComponent } from './components/project-map/project-readme/ ConsoleGuard, Title, ApplianceService, - UpdatesService + UpdatesService, ], entryComponents: [ AddServerDialogComponent, @@ -621,8 +611,8 @@ import { ProjectReadmeComponent } from './components/project-map/project-readme/ EditNetworkConfigurationDialogComponent, ProjectReadmeComponent ], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) export class AppModule { - constructor(protected _googleAnalyticsService: GoogleAnalyticsService) { } + constructor(protected _googleAnalyticsService: GoogleAnalyticsService) {} } diff --git a/src/app/cartography/angular-map.imports.ts b/src/app/cartography/angular-map.imports.ts index e2a53e9f..711585e8 100644 --- a/src/app/cartography/angular-map.imports.ts +++ b/src/app/cartography/angular-map.imports.ts @@ -1,6 +1,4 @@ -import { NodeComponent } from './components/experimental-map/node/node.component'; -import { LinkComponent } from './components/experimental-map/link/link.component'; -import { StatusComponent } from './components/experimental-map/status/status.component'; +import { DraggableComponent } from './components/experimental-map/draggable/draggable.component'; import { DrawingComponent } from './components/experimental-map/drawing/drawing.component'; import { EllipseComponent } from './components/experimental-map/drawing/drawings/ellipse/ellipse.component'; import { ImageComponent } from './components/experimental-map/drawing/drawings/image/image.component'; @@ -8,8 +6,10 @@ import { LineComponent } from './components/experimental-map/drawing/drawings/li import { RectComponent } from './components/experimental-map/drawing/drawings/rect/rect.component'; import { TextComponent } from './components/experimental-map/drawing/drawings/text/text.component'; import { InterfaceLabelComponent } from './components/experimental-map/interface-label/interface-label.component'; -import { DraggableComponent } from './components/experimental-map/draggable/draggable.component'; +import { LinkComponent } from './components/experimental-map/link/link.component'; +import { NodeComponent } from './components/experimental-map/node/node.component'; import { SelectionComponent } from './components/experimental-map/selection/selection.component'; +import { StatusComponent } from './components/experimental-map/status/status.component'; export const ANGULAR_MAP_DECLARATIONS = [ NodeComponent, @@ -23,5 +23,5 @@ export const ANGULAR_MAP_DECLARATIONS = [ TextComponent, DraggableComponent, SelectionComponent, - InterfaceLabelComponent + InterfaceLabelComponent, ]; diff --git a/src/app/cartography/cartography.module.ts b/src/app/cartography/cartography.module.ts index 3ebad213..7d7c813d 100644 --- a/src/app/cartography/cartography.module.ts +++ b/src/app/cartography/cartography.module.ts @@ -1,27 +1,22 @@ -import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; - -import { CssFixer } from './helpers/css-fixer'; -import { FontFixer } from './helpers/font-fixer'; -import { DefaultDrawingsFactory } from './helpers/default-drawings-factory'; -import { MultiLinkCalculatorHelper } from './helpers/multi-link-calculator-helper'; -import { SvgToDrawingConverter } from './helpers/svg-to-drawing-converter'; -import { QtDasharrayFixer } from './helpers/qt-dasharray-fixer'; -import { LayersManager } from './managers/layers-manager'; -import { MapChangeDetectorRef } from './services/map-change-detector-ref'; -import { Context } from './models/context'; import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports'; -import { D3_MAP_IMPORTS } from './d3-map.imports'; -import { CanvasSizeDetector } from './helpers/canvas-size-detector'; -import { DrawingsEventSource } from './events/drawings-event-source'; -import { NodesEventSource } from './events/nodes-event-source'; -import { MapDrawingToSvgConverter } from './converters/map/map-drawing-to-svg-converter'; +import { D3MapComponent } from './components/d3-map/d3-map.component'; +import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component'; +import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component'; +import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component'; +import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component'; +import { SelectionControlComponent } from './components/selection-control/selection-control.component'; +import { SelectionSelectComponent } from './components/selection-select/selection-select.component'; +import { TextEditorComponent } from './components/text-editor/text-editor.component'; import { DrawingToMapDrawingConverter } from './converters/map/drawing-to-map-drawing-converter'; import { LabelToMapLabelConverter } from './converters/map/label-to-map-label-converter'; +import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter'; import { LinkToMapLinkConverter } from './converters/map/link-to-map-link-converter'; import { MapDrawingToDrawingConverter } from './converters/map/map-drawing-to-drawing-converter'; +import { MapDrawingToSvgConverter } from './converters/map/map-drawing-to-svg-converter'; import { MapLabelToLabelConverter } from './converters/map/map-label-to-label-converter'; import { MapLinkNodeToLinkNodeConverter } from './converters/map/map-link-node-to-link-node-converter'; import { MapLinkToLinkConverter } from './converters/map/map-link-to-link-converter'; @@ -31,34 +26,38 @@ import { MapSymbolToSymbolConverter } from './converters/map/map-symbol-to-symbo import { NodeToMapNodeConverter } from './converters/map/node-to-map-node-converter'; import { PortToMapPortConverter } from './converters/map/port-to-map-port-converter'; import { SymbolToMapSymbolConverter } from './converters/map/symbol-to-map-symbol-converter'; -import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter'; -import { GraphDataManager } from './managers/graph-data-manager'; -import { - MapNodesDataSource, - MapLinksDataSource, - MapDrawingsDataSource, - MapSymbolsDataSource -} from './datasources/map-datasource'; -import { LinksEventSource } from './events/links-event-source'; -import { D3MapComponent } from './components/d3-map/d3-map.component'; -import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component'; -import { SelectionEventSource } from './events/selection-event-source'; -import { SelectionControlComponent } from './components/selection-control/selection-control.component'; -import { SelectionSelectComponent } from './components/selection-select/selection-select.component'; -import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component'; -import { MapSettingsManager } from './managers/map-settings-manager'; -import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component'; -import { FontBBoxCalculator } from './helpers/font-bbox-calculator'; import { StylesToFontConverter } from './converters/styles-to-font-converter'; -import { TextElementFactory } from './helpers/drawings-factory/text-element-factory'; -import { EllipseElementFactory } from './helpers/drawings-factory/ellipse-element-factory'; -import { RectangleElementFactory } from './helpers/drawings-factory/rectangle-element-factory'; -import { LineElementFactory } from './helpers/drawings-factory/line-element-factory'; -import { TextEditorComponent } from './components/text-editor/text-editor.component'; -import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component'; -import { MovingEventSource } from './events/moving-event-source'; +import { D3_MAP_IMPORTS } from './d3-map.imports'; +import { + MapDrawingsDataSource, + MapLinksDataSource, + MapNodesDataSource, + MapSymbolsDataSource, +} from './datasources/map-datasource'; import { MovingCanvasDirective } from './directives/moving-canvas.directive'; import { ZoomingCanvasDirective } from './directives/zooming-canvas.directive'; +import { DrawingsEventSource } from './events/drawings-event-source'; +import { LinksEventSource } from './events/links-event-source'; +import { MovingEventSource } from './events/moving-event-source'; +import { NodesEventSource } from './events/nodes-event-source'; +import { SelectionEventSource } from './events/selection-event-source'; +import { CanvasSizeDetector } from './helpers/canvas-size-detector'; +import { CssFixer } from './helpers/css-fixer'; +import { DefaultDrawingsFactory } from './helpers/default-drawings-factory'; +import { EllipseElementFactory } from './helpers/drawings-factory/ellipse-element-factory'; +import { LineElementFactory } from './helpers/drawings-factory/line-element-factory'; +import { RectangleElementFactory } from './helpers/drawings-factory/rectangle-element-factory'; +import { TextElementFactory } from './helpers/drawings-factory/text-element-factory'; +import { FontBBoxCalculator } from './helpers/font-bbox-calculator'; +import { FontFixer } from './helpers/font-fixer'; +import { MultiLinkCalculatorHelper } from './helpers/multi-link-calculator-helper'; +import { QtDasharrayFixer } from './helpers/qt-dasharray-fixer'; +import { SvgToDrawingConverter } from './helpers/svg-to-drawing-converter'; +import { GraphDataManager } from './managers/graph-data-manager'; +import { LayersManager } from './managers/layers-manager'; +import { MapSettingsManager } from './managers/map-settings-manager'; +import { Context } from './models/context'; +import { MapChangeDetectorRef } from './services/map-change-detector-ref'; import { EthernetLinkWidget } from './widgets/links/ethernet-link'; import { SerialLinkWidget } from './widgets/links/serial-link'; @@ -75,7 +74,7 @@ import { SerialLinkWidget } from './widgets/links/serial-link'; SelectionSelectComponent, DraggableSelectionComponent, MovingCanvasDirective, - ZoomingCanvasDirective + ZoomingCanvasDirective, ], providers: [ CssFixer, @@ -122,8 +121,8 @@ import { SerialLinkWidget } from './widgets/links/serial-link'; StylesToFontConverter, EthernetLinkWidget, SerialLinkWidget, - ...D3_MAP_IMPORTS + ...D3_MAP_IMPORTS, ], - exports: [D3MapComponent, ExperimentalMapComponent] + exports: [D3MapComponent, ExperimentalMapComponent], }) export class CartographyModule {} diff --git a/src/app/cartography/components/d3-map/d3-map.component.html b/src/app/cartography/components/d3-map/d3-map.component.html index b409cd50..e166c697 100644 --- a/src/app/cartography/components/d3-map/d3-map.component.html +++ b/src/app/cartography/components/d3-map/d3-map.component.html @@ -1,14 +1,38 @@ - - + + - - + + diff --git a/src/app/cartography/components/d3-map/d3-map.component.spec.ts b/src/app/cartography/components/d3-map/d3-map.component.spec.ts index 110f85cc..007b05f2 100644 --- a/src/app/cartography/components/d3-map/d3-map.component.spec.ts +++ b/src/app/cartography/components/d3-map/d3-map.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { D3MapComponent } from './d3-map.component'; describe('D3MapComponent', () => { @@ -8,7 +7,7 @@ describe('D3MapComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [D3MapComponent] + declarations: [D3MapComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/d3-map/d3-map.component.ts b/src/app/cartography/components/d3-map/d3-map.component.ts index 4a30cc36..b79b3bbe 100644 --- a/src/app/cartography/components/d3-map/d3-map.component.ts +++ b/src/app/cartography/components/d3-map/d3-map.component.ts @@ -7,38 +7,35 @@ import { OnDestroy, OnInit, SimpleChange, - EventEmitter, - Output, - ViewChild + ViewChild, } from '@angular/core'; -import { Selection, select } from 'd3-selection'; - -import { GraphLayout } from '../../widgets/graph-layout'; -import { Context } from '../../models/context'; -import { Size } from '../../models/size'; +import { select, Selection } from 'd3-selection'; import { Subscription } from 'rxjs'; -import { InterfaceLabelWidget } from '../../widgets/interface-label'; -import { SelectionTool } from '../../tools/selection-tool'; -import { MovingTool } from '../../tools/moving-tool'; -import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; -import { CanvasSizeDetector } from '../../helpers/canvas-size-detector'; -import { Node } from '../../models/node'; import { Link } from '../../../models/link'; -import { Drawing } from '../../models/drawing'; +import { Project } from '../../../models/project'; +import { Server } from '../../../models/server'; import { Symbol } from '../../../models/symbol'; +import { MapScaleService } from '../../../services/mapScale.service'; +import { MapSettingsService } from '../../../services/mapsettings.service'; +import { ToolsService } from '../../../services/tools.service'; +import { CanvasSizeDetector } from '../../helpers/canvas-size-detector'; import { GraphDataManager } from '../../managers/graph-data-manager'; import { MapSettingsManager } from '../../managers/map-settings-manager'; -import { Server } from '../../../models/server'; -import { ToolsService } from '../../../services/tools.service'; +import { Context } from '../../models/context'; +import { Drawing } from '../../models/drawing'; +import { Node } from '../../models/node'; +import { Size } from '../../models/size'; +import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; +import { MovingTool } from '../../tools/moving-tool'; +import { SelectionTool } from '../../tools/selection-tool'; +import { GraphLayout } from '../../widgets/graph-layout'; +import { InterfaceLabelWidget } from '../../widgets/interface-label'; import { TextEditorComponent } from '../text-editor/text-editor.component'; -import { MapScaleService } from '../../../services/mapScale.service'; -import { Project } from '../../../models/project'; -import { MapSettingsService } from '../../../services/mapsettings.service'; @Component({ selector: 'app-d3-map', templateUrl: './d3-map.component.html', - styleUrls: ['./d3-map.component.scss'] + styleUrls: ['./d3-map.component.scss'], }) export class D3MapComponent implements OnInit, OnChanges, OnDestroy { @Input() nodes: Node[] = []; @@ -60,7 +57,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { private subscriptions: Subscription[] = []; private drawLinkTool: boolean; protected settings = { - show_interface_labels: true + show_interface_labels: true, }; public gridVisibility: number = 0; @@ -108,7 +105,13 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { if (val) { this.svg.attr('height', window.innerHeight + window.scrollY - 16); } else { - this.svg.attr('height', this.height); + let heightOfProjectWindow = window.innerHeight - 16; + + if (this.height > heightOfProjectWindow) { + this.svg.attr('height', this.height); + } else { + this.svg.attr('height', heightOfProjectWindow); + } } } @@ -142,9 +145,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { } }); - this.subscriptions.push( - this.mapScaleService.scaleChangeEmitter.subscribe((value: number) => this.redraw()) - ); + this.subscriptions.push(this.mapScaleService.scaleChangeEmitter.subscribe((value: number) => this.redraw())); this.subscriptions.push( this.toolsService.isMovingToolActivated.subscribe((value: boolean) => { @@ -166,7 +167,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { ); this.gridVisibility = localStorage.getItem('gridVisibility') === 'true' ? 1 : 0; - this.mapSettingsService.isScrollDisabled.subscribe(val => this.resize(val)); + this.mapSettingsService.isScrollDisabled.subscribe((val) => this.resize(val)); } ngOnDestroy() { @@ -184,10 +185,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { public createGraph(domElement: HTMLElement) { const rootElement = select(domElement); this.svg = rootElement.select('svg'); - this.graphLayout.connect( - this.svg, - this.context - ); + this.graphLayout.connect(this.svg, this.context); this.graphLayout.draw(this.svg, this.context); this.mapChangeDetectorRef.hasBeenDrawn = true; } @@ -221,11 +219,23 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy { } updateGrid() { - if (this.project.grid_size && this.project.grid_size > 0) this.nodeGridX = (this.project.scene_width/2 - (Math.floor(this.project.scene_width/2 / this.project.grid_size) * this.project.grid_size)); - if (this.project.grid_size && this.project.grid_size > 0) this.nodeGridY = (this.project.scene_height/2 - (Math.floor(this.project.scene_height/2 / this.project.grid_size) * this.project.grid_size)); + if (this.project.grid_size && this.project.grid_size > 0) + this.nodeGridX = + this.project.scene_width / 2 - + Math.floor(this.project.scene_width / 2 / this.project.grid_size) * this.project.grid_size; + if (this.project.grid_size && this.project.grid_size > 0) + this.nodeGridY = + this.project.scene_height / 2 - + Math.floor(this.project.scene_height / 2 / this.project.grid_size) * this.project.grid_size; - if (this.project.drawing_grid_size && this.project.drawing_grid_size > 0) this.drawingGridX = (this.project.scene_width/2 - (Math.floor(this.project.scene_width/2 / this.project.drawing_grid_size) * this.project.drawing_grid_size)); - if (this.project.drawing_grid_size && this.project.drawing_grid_size > 0) this.drawingGridY = (this.project.scene_height/2 - (Math.floor(this.project.scene_height/2 / this.project.drawing_grid_size) * this.project.drawing_grid_size)); + if (this.project.drawing_grid_size && this.project.drawing_grid_size > 0) + this.drawingGridX = + this.project.scene_width / 2 - + Math.floor(this.project.scene_width / 2 / this.project.drawing_grid_size) * this.project.drawing_grid_size; + if (this.project.drawing_grid_size && this.project.drawing_grid_size > 0) + this.drawingGridY = + this.project.scene_height / 2 - + Math.floor(this.project.scene_height / 2 / this.project.drawing_grid_size) * this.project.drawing_grid_size; } @HostListener('window:resize', ['$event']) diff --git a/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts b/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts index 2bb40d57..21a994dc 100644 --- a/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts +++ b/src/app/cartography/components/draggable-selection/draggable-selection.component.spec.ts @@ -1,27 +1,26 @@ -import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; - -import { DraggableSelectionComponent } from './draggable-selection.component'; -import { NodesWidget } from '../../widgets/nodes'; -import { DrawingsWidget } from '../../widgets/drawings'; -import { LinksWidget } from '../../widgets/links'; -import { LabelWidget } from '../../widgets/label'; -import { InterfaceLabelWidget } from '../../widgets/interface-label'; -import { SelectionManager } from '../../managers/selection-manager'; -import { SelectionManagerMock } from '../../managers/selection-manager.spec'; -import { NodesEventSource } from '../../events/nodes-event-source'; +import { EventEmitter } from '@angular/core'; +import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { select } from 'd3-selection'; +import { MapSettingsService } from '../../../services/mapsettings.service'; +import { DraggableDrag, DraggableEnd, DraggableStart } from '../../events/draggable'; import { DrawingsEventSource } from '../../events/drawings-event-source'; +import { LinksEventSource } from '../../events/links-event-source'; +import { NodesEventSource } from '../../events/nodes-event-source'; import { GraphDataManager } from '../../managers/graph-data-manager'; import { MockedGraphDataManager } from '../../managers/graph-data-manager.spec'; -import { LinksEventSource } from '../../events/links-event-source'; -import { DraggableStart, DraggableDrag, DraggableEnd } from '../../events/draggable'; -import { MapNode } from '../../models/map/map-node'; -import { EventEmitter } from '@angular/core'; +import { SelectionManager } from '../../managers/selection-manager'; +import { SelectionManagerMock } from '../../managers/selection-manager.spec'; import { MapDrawing } from '../../models/map/map-drawing'; import { MapLabel } from '../../models/map/map-label'; -import { MapLinkNode } from '../../models/map/map-link-node'; -import { select } from 'd3-selection'; import { MapLink } from '../../models/map/map-link'; -import { MapSettingsService } from '../../../services/mapsettings.service'; +import { MapLinkNode } from '../../models/map/map-link-node'; +import { MapNode } from '../../models/map/map-node'; +import { DrawingsWidget } from '../../widgets/drawings'; +import { InterfaceLabelWidget } from '../../widgets/interface-label'; +import { LabelWidget } from '../../widgets/label'; +import { LinksWidget } from '../../widgets/links'; +import { NodesWidget } from '../../widgets/nodes'; +import { DraggableSelectionComponent } from './draggable-selection.component'; describe('DraggableSelectionComponent', () => { let component: DraggableSelectionComponent; @@ -67,8 +66,8 @@ describe('DraggableSelectionComponent', () => { draggable: { start: nodesStartEventEmitter, drag: nodesDragEventEmitter, - end: nodesEndEventEmitter - } + end: nodesEndEventEmitter, + }, }; const drawingsWidgetStub = { @@ -76,11 +75,11 @@ describe('DraggableSelectionComponent', () => { draggable: { start: drawingsStartEventEmitter, drag: drawingsDragEventEmitter, - end: drawingsEndEventEmitter - } + end: drawingsEndEventEmitter, + }, }; const linksWidgetStub = { - redrawLink: () => {} + redrawLink: () => {}, }; const labelWidgetStub = { @@ -88,27 +87,27 @@ describe('DraggableSelectionComponent', () => { draggable: { start: labelStartEventEmitter, drag: labelDragEventEmitter, - end: labelEndEventEmitter - } + end: labelEndEventEmitter, + }, }; const interfaceLabelWidgetStub = { draggable: { start: interfaceLabelStartEventEmitter, drag: interfaceLabelDragEventEmitter, - end: interfaceLabelEndEventEmitter - } + end: interfaceLabelEndEventEmitter, + }, }; const nodesEventSourceStub = { dragged: { emit: () => {} }, - labelDragged: { emit: () => {} } + labelDragged: { emit: () => {} }, }; const drawingsEventSourceStub = { - dragged: { emit: () => {} } + dragged: { emit: () => {} }, }; const linksEventSourceStub = { - interfaceDragged: { emit: () => {} } + interfaceDragged: { emit: () => {} }, }; TestBed.configureTestingModule({ @@ -123,9 +122,9 @@ describe('DraggableSelectionComponent', () => { { provide: DrawingsEventSource, useValue: drawingsEventSourceStub }, { provide: GraphDataManager, useValue: mockedGraphDataManager }, { provide: LinksEventSource, useValue: linksEventSourceStub }, - { provide: MapSettingsService, useClass: MapSettingsService } + { provide: MapSettingsService, useClass: MapSettingsService }, ], - declarations: [DraggableSelectionComponent] + declarations: [DraggableSelectionComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/draggable-selection/draggable-selection.component.ts b/src/app/cartography/components/draggable-selection/draggable-selection.component.ts index ffb73210..988ac140 100644 --- a/src/app/cartography/components/draggable-selection/draggable-selection.component.ts +++ b/src/app/cartography/components/draggable-selection/draggable-selection.component.ts @@ -1,28 +1,28 @@ -import { Component, OnInit, OnDestroy, Input } from '@angular/core'; -import { Subscription, merge } from 'rxjs'; -import { NodesWidget } from '../../widgets/nodes'; -import { DrawingsWidget } from '../../widgets/drawings'; -import { LinksWidget } from '../../widgets/links'; -import { SelectionManager } from '../../managers/selection-manager'; -import { NodesEventSource } from '../../events/nodes-event-source'; -import { DrawingsEventSource } from '../../events/drawings-event-source'; -import { GraphDataManager } from '../../managers/graph-data-manager'; -import { DraggableStart, DraggableDrag, DraggableEnd } from '../../events/draggable'; -import { MapNode } from '../../models/map/map-node'; -import { MapDrawing } from '../../models/map/map-drawing'; -import { DraggedDataEvent } from '../../events/event-source'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { select } from 'd3-selection'; -import { MapLabel } from '../../models/map/map-label'; -import { LabelWidget } from '../../widgets/label'; -import { InterfaceLabelWidget } from '../../widgets/interface-label'; -import { MapLinkNode } from '../../models/map/map-link-node'; -import { LinksEventSource } from '../../events/links-event-source'; +import { merge, Subscription } from 'rxjs'; import { MapSettingsService } from '../../../services/mapsettings.service'; +import { DraggableDrag, DraggableEnd, DraggableStart } from '../../events/draggable'; +import { DrawingsEventSource } from '../../events/drawings-event-source'; +import { DraggedDataEvent } from '../../events/event-source'; +import { LinksEventSource } from '../../events/links-event-source'; +import { NodesEventSource } from '../../events/nodes-event-source'; +import { GraphDataManager } from '../../managers/graph-data-manager'; +import { SelectionManager } from '../../managers/selection-manager'; +import { MapDrawing } from '../../models/map/map-drawing'; +import { MapLabel } from '../../models/map/map-label'; +import { MapLinkNode } from '../../models/map/map-link-node'; +import { MapNode } from '../../models/map/map-node'; +import { DrawingsWidget } from '../../widgets/drawings'; +import { InterfaceLabelWidget } from '../../widgets/interface-label'; +import { LabelWidget } from '../../widgets/label'; +import { LinksWidget } from '../../widgets/links'; +import { NodesWidget } from '../../widgets/nodes'; @Component({ selector: 'app-draggable-selection', templateUrl: './draggable-selection.component.html', - styleUrls: ['./draggable-selection.component.scss'] + styleUrls: ['./draggable-selection.component.scss'], }) export class DraggableSelectionComponent implements OnInit, OnDestroy { private start: Subscription; @@ -62,25 +62,25 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { ).subscribe((evt: DraggableStart) => { const selected = this.selectionManager.getSelected(); if (evt.datum instanceof MapNode) { - if (selected.filter(item => item instanceof MapNode && item.id === evt.datum.id).length === 0) { + if (selected.filter((item) => item instanceof MapNode && item.id === evt.datum.id).length === 0) { this.selectionManager.setSelected([evt.datum]); } } if (evt.datum instanceof MapDrawing) { - if (selected.filter(item => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) { + if (selected.filter((item) => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) { this.selectionManager.setSelected([evt.datum]); } } if (evt.datum instanceof MapLabel) { - if (selected.filter(item => item instanceof MapLabel && item.id === evt.datum.id).length === 0) { + if (selected.filter((item) => item instanceof MapLabel && item.id === evt.datum.id).length === 0) { this.selectionManager.setSelected([evt.datum]); } } if (evt.datum instanceof MapLinkNode) { - if (selected.filter(item => item instanceof MapLinkNode && item.id === evt.datum.id).length === 0) { + if (selected.filter((item) => item instanceof MapLinkNode && item.id === evt.datum.id).length === 0) { this.selectionManager.setSelected([evt.datum]); } } @@ -95,7 +95,7 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { if (!this.isMapLocked) { const selected = this.selectionManager.getSelected(); // update nodes - let mapNodes = selected.filter(item => item instanceof MapNode); + let mapNodes = selected.filter((item) => item instanceof MapNode); const lockedNodes = mapNodes.filter((item: MapNode) => item.locked); const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked); selectedNodes.forEach((node: MapNode) => { @@ -107,18 +107,18 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { const links = this.graphDataManager .getLinks() .filter( - link => + (link) => (link.target !== undefined && link.target.id === node.id) || (link.source !== undefined && link.source.id === node.id) ); - links.forEach(link => { + links.forEach((link) => { this.linksWidget.redrawLink(svg, link); }); }); // update drawings - let mapDrawings = selected.filter(item => item instanceof MapDrawing); + let mapDrawings = selected.filter((item) => item instanceof MapDrawing); const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked); selectedDrawings.forEach((drawing: MapDrawing) => { drawing.x += evt.dx; @@ -127,32 +127,36 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { }); // update labels - let mapLabels = selected.filter(item => item instanceof MapLabel); - const selectedLabels = mapLabels.filter((item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0); + let mapLabels = selected.filter((item) => item instanceof MapLabel); + const selectedLabels = mapLabels.filter( + (item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0 + ); selectedLabels.forEach((label: MapLabel) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; + const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0; if (isParentNodeSelected) { return; } - const node = this.graphDataManager.getNodes().filter(node => node.id === label.nodeId)[0]; + const node = this.graphDataManager.getNodes().filter((node) => node.id === label.nodeId)[0]; node.label.x += evt.dx; node.label.y += evt.dy; this.labelWidget.redrawLabel(svg, label); }); // update interface labels - let mapLinkNodes = selected.filter(item => item instanceof MapLinkNode); - const selectedLinkNodes = mapLinkNodes.filter((item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0); + let mapLinkNodes = selected.filter((item) => item instanceof MapLinkNode); + const selectedLinkNodes = mapLinkNodes.filter( + (item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0 + ); selectedLinkNodes.forEach((interfaceLabel: MapLinkNode) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === interfaceLabel.nodeId).length > 0; + const isParentNodeSelected = selectedNodes.filter((node) => node.id === interfaceLabel.nodeId).length > 0; if (isParentNodeSelected) { return; } const link = this.graphDataManager .getLinks() - .filter(link => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0]; + .filter((link) => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0]; if (link.nodes[0].id === interfaceLabel.id) { link.nodes[0].label.x += evt.dx; link.nodes[0].label.y += evt.dy; @@ -176,23 +180,25 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { if (!this.isMapLocked) { const selected = this.selectionManager.getSelected(); - let mapNodes = selected.filter(item => item instanceof MapNode); + let mapNodes = selected.filter((item) => item instanceof MapNode); const lockedNodes = mapNodes.filter((item: MapNode) => item.locked); const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked); selectedNodes.forEach((item: MapNode) => { this.nodesEventSource.dragged.emit(new DraggedDataEvent(item, evt.dx, evt.dy)); }); - let mapDrawings = selected.filter(item => item instanceof MapDrawing); + let mapDrawings = selected.filter((item) => item instanceof MapDrawing); const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked); selectedDrawings.forEach((item: MapDrawing) => { this.drawingsEventSource.dragged.emit(new DraggedDataEvent(item, evt.dx, evt.dy)); }); - let mapLabels = selected.filter(item => item instanceof MapLabel); - const selectedLabels = mapLabels.filter((item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0); + let mapLabels = selected.filter((item) => item instanceof MapLabel); + const selectedLabels = mapLabels.filter( + (item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0 + ); selectedLabels.forEach((label: MapLabel) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; + const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0; if (isParentNodeSelected) { return; } @@ -200,10 +206,12 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy { this.nodesEventSource.labelDragged.emit(new DraggedDataEvent(label, evt.dx, evt.dy)); }); - let mapLinkNodes = selected.filter(item => item instanceof MapLinkNode); - const selectedLinkNodes = mapLinkNodes.filter((item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0) + let mapLinkNodes = selected.filter((item) => item instanceof MapLinkNode); + const selectedLinkNodes = mapLinkNodes.filter( + (item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0 + ); selectedLinkNodes.forEach((label: MapLinkNode) => { - const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0; + const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0; if (isParentNodeSelected) { return; } diff --git a/src/app/cartography/components/drawing-adding/drawing-adding.component.spec.ts b/src/app/cartography/components/drawing-adding/drawing-adding.component.spec.ts index f8854882..ea508b70 100644 --- a/src/app/cartography/components/drawing-adding/drawing-adding.component.spec.ts +++ b/src/app/cartography/components/drawing-adding/drawing-adding.component.spec.ts @@ -1,8 +1,8 @@ -import { DrawingAddingComponent } from './drawing-adding.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { DrawingsEventSource } from '../../events/drawings-event-source'; import { Context } from '../../models/context'; +import { DrawingAddingComponent } from './drawing-adding.component'; describe('DrawingAddingComponent', () => { let component: DrawingAddingComponent; @@ -14,9 +14,9 @@ describe('DrawingAddingComponent', () => { imports: [NoopAnimationsModule], providers: [ { provide: DrawingsEventSource, useValue: drawingsEventSource }, - { provide: Context, useClass: Context } + { provide: Context, useClass: Context }, ], - declarations: [DrawingAddingComponent] + declarations: [DrawingAddingComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/drawing-adding/drawing-adding.component.ts b/src/app/cartography/components/drawing-adding/drawing-adding.component.ts index cc380967..b8994561 100644 --- a/src/app/cartography/components/drawing-adding/drawing-adding.component.ts +++ b/src/app/cartography/components/drawing-adding/drawing-adding.component.ts @@ -1,13 +1,13 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { Context } from '../../models/context'; +import { Subscription } from 'rxjs'; import { DrawingsEventSource } from '../../events/drawings-event-source'; import { AddedDataEvent } from '../../events/event-source'; -import { Subscription } from 'rxjs'; +import { Context } from '../../models/context'; @Component({ selector: 'app-drawing-adding', templateUrl: './drawing-adding.component.html', - styleUrls: ['./drawing-adding.component.scss'] + styleUrls: ['./drawing-adding.component.scss'], }) export class DrawingAddingComponent implements OnInit, OnDestroy { @Input('svg') svg: SVGSVGElement; @@ -18,15 +18,19 @@ export class DrawingAddingComponent implements OnInit, OnDestroy { constructor(private drawingsEventSource: DrawingsEventSource, private context: Context) {} ngOnInit() { - this.drawingSelected = this.drawingsEventSource.selected.subscribe(evt => { + this.drawingSelected = this.drawingsEventSource.selected.subscribe((evt) => { evt === '' ? this.deactivate() : this.activate(); }); } activate() { let listener = (event: MouseEvent) => { - let x = (event.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x))/this.context.transformation.k; - let y = (event.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y))/this.context.transformation.k; + let x = + (event.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)) / + this.context.transformation.k; + let y = + (event.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)) / + this.context.transformation.k; this.drawingsEventSource.pointToAddSelected.emit(new AddedDataEvent(x, y)); this.deactivate(); diff --git a/src/app/cartography/components/drawing-resizing/drawing-resizing.component.spec.ts b/src/app/cartography/components/drawing-resizing/drawing-resizing.component.spec.ts index 9b530960..7cd3fac2 100644 --- a/src/app/cartography/components/drawing-resizing/drawing-resizing.component.spec.ts +++ b/src/app/cartography/components/drawing-resizing/drawing-resizing.component.spec.ts @@ -1,12 +1,11 @@ -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; - -import { DrawingResizingComponent } from './drawing-resizing.component'; -import { DrawingsWidget } from '../../widgets/drawings'; -import { DrawingsEventSource } from '../../events/drawings-event-source'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { EventEmitter } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { DrawingsEventSource } from '../../events/drawings-event-source'; import { ResizingEnd } from '../../events/resizing'; import { MapDrawing } from '../../models/map/map-drawing'; +import { DrawingsWidget } from '../../widgets/drawings'; +import { DrawingResizingComponent } from './drawing-resizing.component'; export class DrawingWidgetMock { resizingFinished = new EventEmitter>(); @@ -36,9 +35,9 @@ describe('DrawingResizingComponent', () => { imports: [NoopAnimationsModule], providers: [ { provide: DrawingsWidget, useValue: drawingsWidgetMock }, - { provide: DrawingsEventSource, useValue: drawingsEventSource } + { provide: DrawingsEventSource, useValue: drawingsEventSource }, ], - declarations: [DrawingResizingComponent] + declarations: [DrawingResizingComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/drawing-resizing/drawing-resizing.component.ts b/src/app/cartography/components/drawing-resizing/drawing-resizing.component.ts index 05c654c1..015ad485 100644 --- a/src/app/cartography/components/drawing-resizing/drawing-resizing.component.ts +++ b/src/app/cartography/components/drawing-resizing/drawing-resizing.component.ts @@ -1,17 +1,15 @@ -import { Component, OnInit, ElementRef, OnDestroy, Input, Output, EventEmitter } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { DrawingsEventSource } from '../../events/drawings-event-source'; -import { DrawingsWidget } from '../../widgets/drawings'; -import { MapDrawing } from '../../models/map/map-drawing'; import { ResizedDataEvent } from '../../events/event-source'; import { ResizingEnd } from '../../events/resizing'; +import { MapDrawing } from '../../models/map/map-drawing'; +import { DrawingsWidget } from '../../widgets/drawings'; @Component({ selector: 'app-drawing-resizing', - template: ` - - `, - styleUrls: ['./drawing-resizing.component.scss'] + template: ` `, + styleUrls: ['./drawing-resizing.component.scss'], }) export class DrawingResizingComponent implements OnInit, OnDestroy { resizingFinished: Subscription; diff --git a/src/app/cartography/components/experimental-map/draggable/draggable.component.spec.ts b/src/app/cartography/components/experimental-map/draggable/draggable.component.spec.ts index 5712ef99..3182c040 100644 --- a/src/app/cartography/components/experimental-map/draggable/draggable.component.spec.ts +++ b/src/app/cartography/components/experimental-map/draggable/draggable.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { DraggableComponent } from './draggable.component'; describe('DraggableComponent', () => { @@ -8,7 +7,7 @@ describe('DraggableComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [DraggableComponent] + declarations: [DraggableComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/draggable/draggable.component.ts b/src/app/cartography/components/experimental-map/draggable/draggable.component.ts index d1207a80..b039a610 100644 --- a/src/app/cartography/components/experimental-map/draggable/draggable.component.ts +++ b/src/app/cartography/components/experimental-map/draggable/draggable.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ElementRef, AfterViewInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { Point } from '../../../models/point'; @@ -8,10 +8,8 @@ export class DraggableDraggedEvent { @Component({ selector: '[app-draggable]', - template: ` - - `, - styleUrls: ['./draggable.component.scss'] + template: ` `, + styleUrls: ['./draggable.component.scss'], }) export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy { @Input('app-draggable') item: Point; diff --git a/src/app/cartography/components/experimental-map/drawing/drawing.component.spec.ts b/src/app/cartography/components/experimental-map/drawing/drawing.component.spec.ts index 4578bb54..b07d4b9f 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawing.component.spec.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawing.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { DrawingComponent } from './drawing.component'; describe('DrawingComponent', () => { @@ -8,7 +7,7 @@ describe('DrawingComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [DrawingComponent] + declarations: [DrawingComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/drawing/drawing.component.ts b/src/app/cartography/components/experimental-map/drawing/drawing.component.ts index dfd9cc9f..f8bc603f 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawing.component.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawing.component.ts @@ -1,18 +1,18 @@ -import { Component, OnInit, Input, ChangeDetectorRef } from '@angular/core'; +import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; +import { DrawingsEventSource } from '../../../events/drawings-event-source'; +import { DraggedDataEvent } from '../../../events/event-source'; +import { SvgToDrawingConverter } from '../../../helpers/svg-to-drawing-converter'; import { EllipseElement } from '../../../models/drawings/ellipse-element'; import { ImageElement } from '../../../models/drawings/image-element'; import { LineElement } from '../../../models/drawings/line-element'; import { RectElement } from '../../../models/drawings/rect-element'; import { TextElement } from '../../../models/drawings/text-element'; -import { SvgToDrawingConverter } from '../../../helpers/svg-to-drawing-converter'; -import { DraggedDataEvent } from '../../../events/event-source'; import { MapDrawing } from '../../../models/map/map-drawing'; -import { DrawingsEventSource } from '../../../events/drawings-event-source'; @Component({ selector: '[app-drawing]', templateUrl: './drawing.component.html', - styleUrls: ['./drawing.component.scss'] + styleUrls: ['./drawing.component.scss'], }) export class DrawingComponent implements OnInit { @Input('app-drawing') drawing: MapDrawing; diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.spec.ts b/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.spec.ts index 6fe0e0d8..1e8c38d8 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.spec.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { EllipseComponent } from './ellipse.component'; describe('EllipseComponent', () => { @@ -8,7 +7,7 @@ describe('EllipseComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [EllipseComponent] + declarations: [EllipseComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.ts b/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.ts index f1437436..74b3f11e 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/ellipse/ellipse.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { EllipseElement } from '../../../../../models/drawings/ellipse-element'; +import { Component, Input, OnInit } from '@angular/core'; import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer'; +import { EllipseElement } from '../../../../../models/drawings/ellipse-element'; @Component({ selector: '[app-ellipse]', templateUrl: './ellipse.component.html', - styleUrls: ['./ellipse.component.scss'] + styleUrls: ['./ellipse.component.scss'], }) export class EllipseComponent implements OnInit { @Input('app-ellipse') ellipse: EllipseElement; diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.spec.ts b/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.spec.ts index 6ee6952c..65bf9959 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.spec.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { ImageComponent } from './image.component'; describe('ImageComponent', () => { @@ -8,7 +7,7 @@ describe('ImageComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ImageComponent] + declarations: [ImageComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.ts b/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.ts index 5ddd968c..b8151e68 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/image/image.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { ImageElement } from '../../../../../models/drawings/image-element'; @Component({ selector: '[app-image]', templateUrl: './image.component.html', - styleUrls: ['./image.component.scss'] + styleUrls: ['./image.component.scss'], }) export class ImageComponent implements OnInit { @Input('app-image') image: ImageElement; diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.spec.ts b/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.spec.ts index 3f83bf9e..c6cfb82a 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.spec.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { LineComponent } from './line.component'; describe('LineComponent', () => { @@ -8,7 +7,7 @@ describe('LineComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [LineComponent] + declarations: [LineComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.ts b/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.ts index ae6018b1..175d66a4 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/line/line.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer'; import { LineElement } from '../../../../../models/drawings/line-element'; @Component({ selector: '[app-line]', templateUrl: './line.component.html', - styleUrls: ['./line.component.scss'] + styleUrls: ['./line.component.scss'], }) export class LineComponent implements OnInit { @Input('app-line') line: LineElement; diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.spec.ts b/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.spec.ts index 949ca269..17c35d33 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.spec.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { RectComponent } from './rect.component'; describe('RectComponent', () => { @@ -8,7 +7,7 @@ describe('RectComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [RectComponent] + declarations: [RectComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.ts b/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.ts index 4caa423f..3fc17a26 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/rect/rect.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { RectElement } from '../../../../../models/drawings/rect-element'; +import { Component, Input, OnInit } from '@angular/core'; import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer'; +import { RectElement } from '../../../../../models/drawings/rect-element'; @Component({ selector: '[app-rect]', templateUrl: './rect.component.html', - styleUrls: ['./rect.component.scss'] + styleUrls: ['./rect.component.scss'], }) export class RectComponent implements OnInit { @Input('app-rect') rect: RectElement; diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.spec.ts b/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.spec.ts index 87012b5c..5dfb1368 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.spec.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { TextComponent } from './text.component'; describe('TextComponent', () => { @@ -8,7 +7,7 @@ describe('TextComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [TextComponent] + declarations: [TextComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.ts b/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.ts index c1f97e1c..2292278b 100644 --- a/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.ts +++ b/src/app/cartography/components/experimental-map/drawing/drawings/text/text.component.ts @@ -1,12 +1,12 @@ -import { Component, OnInit, Input, ViewChild, ElementRef, DoCheck } from '@angular/core'; +import { Component, DoCheck, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; -import { TextElement } from '../../../../../models/drawings/text-element'; import { FontFixer } from '../../../../../helpers/font-fixer'; +import { TextElement } from '../../../../../models/drawings/text-element'; @Component({ selector: '[app-text]', templateUrl: './text.component.html', - styleUrls: ['./text.component.scss'] + styleUrls: ['./text.component.scss'], }) export class TextComponent implements OnInit, DoCheck { static MARGIN = 4; diff --git a/src/app/cartography/components/experimental-map/experimental-map.component.ts b/src/app/cartography/components/experimental-map/experimental-map.component.ts index d5b0708e..36f96ca2 100644 --- a/src/app/cartography/components/experimental-map/experimental-map.component.ts +++ b/src/app/cartography/components/experimental-map/experimental-map.component.ts @@ -1,4 +1,6 @@ import { + ChangeDetectionStrategy, + ChangeDetectorRef, Component, ElementRef, HostListener, @@ -7,29 +9,26 @@ import { OnDestroy, OnInit, SimpleChange, - ChangeDetectionStrategy, - ChangeDetectorRef, - ViewChild + ViewChild, } from '@angular/core'; - -import { GraphLayout } from '../../widgets/graph-layout'; -import { Context } from '../../models/context'; -import { Size } from '../../models/size'; import { Subscription } from 'rxjs'; -import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; -import { CanvasSizeDetector } from '../../helpers/canvas-size-detector'; -import { Node } from '../../models/node'; import { Link } from '../../../models/link'; -import { Drawing } from '../../models/drawing'; import { Symbol } from '../../../models/symbol'; +import { CanvasSizeDetector } from '../../helpers/canvas-size-detector'; import { GraphDataManager } from '../../managers/graph-data-manager'; import { LayersManager } from '../../managers/layers-manager'; +import { Context } from '../../models/context'; +import { Drawing } from '../../models/drawing'; +import { Node } from '../../models/node'; +import { Size } from '../../models/size'; +import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; +import { GraphLayout } from '../../widgets/graph-layout'; @Component({ selector: 'app-experimental-map', templateUrl: './experimental-map.component.html', styleUrls: ['./experimental-map.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy { @Input() nodes: Node[] = []; @@ -48,7 +47,7 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy { private changesDetected: Subscription; protected settings = { - show_interface_labels: true + show_interface_labels: true, }; constructor( diff --git a/src/app/cartography/components/experimental-map/interface-label/interface-label.component.spec.ts b/src/app/cartography/components/experimental-map/interface-label/interface-label.component.spec.ts index 93c68e13..70e8d378 100644 --- a/src/app/cartography/components/experimental-map/interface-label/interface-label.component.spec.ts +++ b/src/app/cartography/components/experimental-map/interface-label/interface-label.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { InterfaceLabelComponent } from './interface-label.component'; describe('InterfaceLabelComponent', () => { @@ -8,7 +7,7 @@ describe('InterfaceLabelComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [InterfaceLabelComponent] + declarations: [InterfaceLabelComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/interface-label/interface-label.component.ts b/src/app/cartography/components/experimental-map/interface-label/interface-label.component.ts index 0a2c8921..cd316ec9 100644 --- a/src/app/cartography/components/experimental-map/interface-label/interface-label.component.ts +++ b/src/app/cartography/components/experimental-map/interface-label/interface-label.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit, Input, ChangeDetectorRef, ElementRef, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { CssFixer } from '../../../helpers/css-fixer'; @Component({ selector: '[app-interface-label]', templateUrl: './interface-label.component.html', - styleUrls: ['./interface-label.component.scss'] + styleUrls: ['./interface-label.component.scss'], }) export class InterfaceLabelComponent implements OnInit { @Input('app-interface-label') ignore: any; @@ -17,7 +17,7 @@ export class InterfaceLabelComponent implements OnInit { y: 0, text: '', style: '', - rotation: 0 + rotation: 0, }; borderSize = 5; diff --git a/src/app/cartography/components/experimental-map/link/link.component.spec.ts b/src/app/cartography/components/experimental-map/link/link.component.spec.ts index 127cafff..f1e1960b 100644 --- a/src/app/cartography/components/experimental-map/link/link.component.spec.ts +++ b/src/app/cartography/components/experimental-map/link/link.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { LinkComponent } from './link.component'; describe('LinkComponent', () => { @@ -8,7 +7,7 @@ describe('LinkComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [LinkComponent] + declarations: [LinkComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/link/link.component.ts b/src/app/cartography/components/experimental-map/link/link.component.ts index f89139dc..80069d94 100644 --- a/src/app/cartography/components/experimental-map/link/link.component.ts +++ b/src/app/cartography/components/experimental-map/link/link.component.ts @@ -1,25 +1,25 @@ import { + ChangeDetectorRef, Component, - OnInit, - Input, - ViewChild, ElementRef, EventEmitter, - ChangeDetectorRef, - OnDestroy + Input, + OnDestroy, + OnInit, + ViewChild, } from '@angular/core'; import { Subscription } from 'rxjs'; -import { LinkStrategy } from './strategies/link-strategy'; -import { EthernetLinkStrategy } from './strategies/ethernet-link-strategy'; -import { SerialLinkStrategy } from './strategies/serial-link-strategy'; import { MultiLinkCalculatorHelper } from '../../../helpers/multi-link-calculator-helper'; -import { Node } from '../../../models/node'; import { MapLink } from '../../../models/map/map-link'; +import { Node } from '../../../models/node'; +import { EthernetLinkStrategy } from './strategies/ethernet-link-strategy'; +import { LinkStrategy } from './strategies/link-strategy'; +import { SerialLinkStrategy } from './strategies/serial-link-strategy'; @Component({ selector: '[app-link]', templateUrl: './link.component.html', - styleUrls: ['./link.component.scss'] + styleUrls: ['./link.component.scss'], }) export class LinkComponent implements OnInit, OnDestroy { @Input('app-link') link: MapLink; diff --git a/src/app/cartography/components/experimental-map/link/strategies/ethernet-link-strategy.ts b/src/app/cartography/components/experimental-map/link/strategies/ethernet-link-strategy.ts index a3df16a1..98d2d1ba 100644 --- a/src/app/cartography/components/experimental-map/link/strategies/ethernet-link-strategy.ts +++ b/src/app/cartography/components/experimental-map/link/strategies/ethernet-link-strategy.ts @@ -1,12 +1,12 @@ -import { LinkStrategy } from './link-strategy'; import { path } from 'd3-path'; import { MapLink } from '../../../../models/map/map-link'; +import { LinkStrategy } from './link-strategy'; export class EthernetLinkStrategy implements LinkStrategy { public d(link: MapLink): string { const points = [ [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(); diff --git a/src/app/cartography/components/experimental-map/link/strategies/serial-link-strategy.ts b/src/app/cartography/components/experimental-map/link/strategies/serial-link-strategy.ts index 4f0a04fe..c3872aaa 100644 --- a/src/app/cartography/components/experimental-map/link/strategies/serial-link-strategy.ts +++ b/src/app/cartography/components/experimental-map/link/strategies/serial-link-strategy.ts @@ -1,16 +1,16 @@ import { path } from 'd3-path'; -import { LinkStrategy } from './link-strategy'; import { MapLink } from '../../../../models/map/map-link'; +import { LinkStrategy } from './link-strategy'; export class SerialLinkStrategy implements LinkStrategy { private linkToPoints(link: MapLink) { const source = { x: link.source.x + link.source.width / 2, - y: link.source.y + link.source.height / 2 + y: link.source.y + link.source.height / 2, }; const target = { x: link.target.x + link.target.width / 2, - y: link.target.y + link.target.height / 2 + y: link.target.y + link.target.height / 2, }; const dx = target.x - source.x; @@ -22,12 +22,12 @@ export class SerialLinkStrategy implements LinkStrategy { const angle_source: [number, number] = [ source.x + dx / 2.0 + 15 * vect_rot[0], - source.y + dy / 2.0 + 15 * vect_rot[1] + source.y + dy / 2.0 + 15 * vect_rot[1], ]; const angle_target: [number, number] = [ target.x - dx / 2.0 - 15 * vect_rot[0], - target.y - dy / 2.0 - 15 * vect_rot[1] + target.y - dy / 2.0 - 15 * vect_rot[1], ]; return [[source.x, source.y], angle_source, angle_target, [target.x, target.y]]; diff --git a/src/app/cartography/components/experimental-map/node/node.component.spec.ts b/src/app/cartography/components/experimental-map/node/node.component.spec.ts index 76c09dc4..c35dda52 100644 --- a/src/app/cartography/components/experimental-map/node/node.component.spec.ts +++ b/src/app/cartography/components/experimental-map/node/node.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { NodeComponent } from './node.component'; describe('NodeComponent', () => { @@ -8,7 +7,7 @@ describe('NodeComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [NodeComponent] + declarations: [NodeComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/node/node.component.ts b/src/app/cartography/components/experimental-map/node/node.component.ts index 896ec653..cea785f2 100644 --- a/src/app/cartography/components/experimental-map/node/node.component.ts +++ b/src/app/cartography/components/experimental-map/node/node.component.ts @@ -1,31 +1,30 @@ import { - Component, - OnInit, - Input, - ElementRef, - ViewChild, - ChangeDetectorRef, + AfterViewInit, ChangeDetectionStrategy, - Output, + ChangeDetectorRef, + Component, + ElementRef, EventEmitter, - OnDestroy, + Input, OnChanges, - AfterViewInit + OnDestroy, + OnInit, + ViewChild, } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { Subscription } from 'rxjs'; +import { Symbol } from '../../../../models/symbol'; +import { DraggedDataEvent } from '../../../events/event-source'; +import { NodesEventSource } from '../../../events/nodes-event-source'; import { CssFixer } from '../../../helpers/css-fixer'; import { FontFixer } from '../../../helpers/font-fixer'; -import { Symbol } from '../../../../models/symbol'; import { MapNode } from '../../../models/map/map-node'; -import { NodesEventSource } from '../../../events/nodes-event-source'; -import { DraggedDataEvent } from '../../../events/event-source'; @Component({ selector: '[app-node]', templateUrl: './node.component.html', styleUrls: ['./node.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit { static NODE_LABEL_MARGIN = 3; diff --git a/src/app/cartography/components/experimental-map/selection/selection.component.spec.ts b/src/app/cartography/components/experimental-map/selection/selection.component.spec.ts index 9cf81f57..94c95763 100644 --- a/src/app/cartography/components/experimental-map/selection/selection.component.spec.ts +++ b/src/app/cartography/components/experimental-map/selection/selection.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { SelectionComponent } from './selection.component'; describe('SelectionComponent', () => { @@ -8,7 +7,7 @@ describe('SelectionComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [SelectionComponent] + declarations: [SelectionComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/selection/selection.component.ts b/src/app/cartography/components/experimental-map/selection/selection.component.ts index cc51bc47..f2d915a4 100644 --- a/src/app/cartography/components/experimental-map/selection/selection.component.ts +++ b/src/app/cartography/components/experimental-map/selection/selection.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit, Input, AfterViewInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core'; -import { Observable, Subscription, Subject } from 'rxjs'; +import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Observable, Subscription } from 'rxjs'; import { Rectangle } from '../../../models/rectangle'; @Component({ selector: '[app-selection]', templateUrl: './selection.component.html', - styleUrls: ['./selection.component.scss'] + styleUrls: ['./selection.component.scss'], }) export class SelectionComponent implements OnInit, AfterViewInit { @Input('app-selection') svg: SVGSVGElement; diff --git a/src/app/cartography/components/experimental-map/status/status.component.spec.ts b/src/app/cartography/components/experimental-map/status/status.component.spec.ts index d4f8f4a9..51032287 100644 --- a/src/app/cartography/components/experimental-map/status/status.component.spec.ts +++ b/src/app/cartography/components/experimental-map/status/status.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { StatusComponent } from './status.component'; describe('StatusComponent', () => { @@ -8,7 +7,7 @@ describe('StatusComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [StatusComponent] + declarations: [StatusComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/experimental-map/status/status.component.ts b/src/app/cartography/components/experimental-map/status/status.component.ts index af2d9dab..bc30e11c 100644 --- a/src/app/cartography/components/experimental-map/status/status.component.ts +++ b/src/app/cartography/components/experimental-map/status/status.component.ts @@ -1,9 +1,9 @@ -import { Component, ElementRef, Input, ChangeDetectorRef } from '@angular/core'; +import { ChangeDetectorRef, Component, ElementRef, Input } from '@angular/core'; @Component({ selector: '[app-status]', templateUrl: './status.component.html', - styleUrls: ['./status.component.scss'] + styleUrls: ['./status.component.scss'], }) export class StatusComponent { static STOPPED_STATUS_RECT_WIDTH = 10; @@ -12,7 +12,7 @@ export class StatusComponent { status: '', path: null, direction: null, - d: null + d: null, }; constructor(protected element: ElementRef, private ref: ChangeDetectorRef) {} diff --git a/src/app/cartography/components/selection-control/selection-control.component.spec.ts b/src/app/cartography/components/selection-control/selection-control.component.spec.ts index 3299b5a3..6952edda 100644 --- a/src/app/cartography/components/selection-control/selection-control.component.spec.ts +++ b/src/app/cartography/components/selection-control/selection-control.component.spec.ts @@ -1,14 +1,13 @@ import { fakeAsync, tick } from '@angular/core/testing'; - -import { SelectionControlComponent } from './selection-control.component'; -import { SelectionManager } from '../../managers/selection-manager'; +import { instance, mock, when } from 'ts-mockito'; import { SelectionEventSource } from '../../events/selection-event-source'; -import { mock, when, instance } from 'ts-mockito'; -import { GraphDataManager } from '../../managers/graph-data-manager'; -import { MapNode } from '../../models/map/map-node'; -import { MapLink } from '../../models/map/map-link'; import { InRectangleHelper } from '../../helpers/in-rectangle-helper'; +import { GraphDataManager } from '../../managers/graph-data-manager'; +import { SelectionManager } from '../../managers/selection-manager'; +import { MapLink } from '../../models/map/map-link'; +import { MapNode } from '../../models/map/map-node'; import { Rectangle } from '../../models/rectangle'; +import { SelectionControlComponent } from './selection-control.component'; describe('SelectionControlComponent', () => { let component: SelectionControlComponent; diff --git a/src/app/cartography/components/selection-control/selection-control.component.ts b/src/app/cartography/components/selection-control/selection-control.component.ts index 52ed1c6a..2f50d276 100644 --- a/src/app/cartography/components/selection-control/selection-control.component.ts +++ b/src/app/cartography/components/selection-control/selection-control.component.ts @@ -1,15 +1,15 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { SelectionEventSource } from '../../events/selection-event-source'; -import { GraphDataManager } from '../../managers/graph-data-manager'; import { InRectangleHelper } from '../../helpers/in-rectangle-helper'; +import { GraphDataManager } from '../../managers/graph-data-manager'; import { SelectionManager } from '../../managers/selection-manager'; import { Rectangle } from '../../models/rectangle'; @Component({ selector: 'app-selection-control', templateUrl: './selection-control.component.html', - styleUrls: ['./selection-control.component.scss'] + styleUrls: ['./selection-control.component.scss'], }) export class SelectionControlComponent implements OnInit, OnDestroy { private onSelection: Subscription; @@ -23,21 +23,21 @@ export class SelectionControlComponent implements OnInit, OnDestroy { ngOnInit() { this.onSelection = this.selectionEventSource.selected.subscribe((rectangle: Rectangle) => { - const selectedNodes = this.graphDataManager.getNodes().filter(node => { + const selectedNodes = this.graphDataManager.getNodes().filter((node) => { return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y); }); - const selectedLinks = this.graphDataManager.getLinks().filter(link => { + const selectedLinks = this.graphDataManager.getLinks().filter((link) => { return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y); }); - const selectedDrawings = this.graphDataManager.getDrawings().filter(drawing => { + const selectedDrawings = this.graphDataManager.getDrawings().filter((drawing) => { return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y); }); const selectedLabels = this.graphDataManager .getNodes() - .filter(node => { + .filter((node) => { if (node.label === undefined) { return false; } @@ -45,11 +45,11 @@ export class SelectionControlComponent implements OnInit, OnDestroy { const labelY = node.y + node.label.y; return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY); }) - .map(node => node.label); + .map((node) => node.label); const selectedInterfacesLabelsSources = this.graphDataManager .getLinks() - .filter(link => { + .filter((link) => { if (link.source === undefined || link.nodes.length != 2 || link.nodes[0].label === undefined) { return false; } @@ -57,11 +57,11 @@ export class SelectionControlComponent implements OnInit, OnDestroy { const interfaceLabelY = link.source.y + link.nodes[0].label.y; return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY); }) - .map(link => link.nodes[0]); + .map((link) => link.nodes[0]); const selectedInterfacesLabelsTargets = this.graphDataManager .getLinks() - .filter(link => { + .filter((link) => { if (link.target === undefined || link.nodes.length != 2 || link.nodes[1].label === undefined) { return false; } @@ -69,7 +69,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy { const interfaceLabelY = link.target.y + link.nodes[1].label.y; return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY); }) - .map(link => link.nodes[1]); + .map((link) => link.nodes[1]); const selectedInterfaces = [...selectedInterfacesLabelsSources, ...selectedInterfacesLabelsTargets]; @@ -78,7 +78,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy { ...selectedLinks, ...selectedDrawings, ...selectedLabels, - ...selectedInterfaces + ...selectedInterfaces, ]; this.selectionManager.setSelected(selected); diff --git a/src/app/cartography/components/selection-select/selection-select.component.spec.ts b/src/app/cartography/components/selection-select/selection-select.component.spec.ts index 4117b6cb..f819be27 100644 --- a/src/app/cartography/components/selection-select/selection-select.component.spec.ts +++ b/src/app/cartography/components/selection-select/selection-select.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { SelectionSelectComponent } from './selection-select.component'; describe('SelectionSelectComponent', () => { @@ -8,7 +7,7 @@ describe('SelectionSelectComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [SelectionSelectComponent] + declarations: [SelectionSelectComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/selection-select/selection-select.component.ts b/src/app/cartography/components/selection-select/selection-select.component.ts index a1ca43e7..28d615b4 100644 --- a/src/app/cartography/components/selection-select/selection-select.component.ts +++ b/src/app/cartography/components/selection-select/selection-select.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { SelectionManager } from '../../managers/selection-manager'; import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; @@ -6,16 +6,13 @@ import { MapChangeDetectorRef } from '../../services/map-change-detector-ref'; @Component({ selector: 'app-selection-select', templateUrl: './selection-select.component.html', - styleUrls: ['./selection-select.component.scss'] + styleUrls: ['./selection-select.component.scss'], }) export class SelectionSelectComponent implements OnInit, OnDestroy { private onSelected: Subscription; private onUnselected: Subscription; - constructor( - private selectionManager: SelectionManager, - private mapChangeDetectorRef: MapChangeDetectorRef - ) {} + constructor(private selectionManager: SelectionManager, private mapChangeDetectorRef: MapChangeDetectorRef) {} ngOnInit() { this.onSelected = this.selectionManager.selected.subscribe(() => { diff --git a/src/app/cartography/components/text-editor/text-editor.component.spec.ts b/src/app/cartography/components/text-editor/text-editor.component.spec.ts index 15836896..7619b5c0 100644 --- a/src/app/cartography/components/text-editor/text-editor.component.spec.ts +++ b/src/app/cartography/components/text-editor/text-editor.component.spec.ts @@ -1,17 +1,17 @@ -import { TextEditorComponent } from './text-editor.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { DrawingsEventSource } from '../../events/drawings-event-source'; -import { ToolsService } from '../../../services/tools.service'; -import { Context } from '../../models/context'; import { Renderer2 } from '@angular/core'; -import { MapScaleService } from '../../../services/mapScale.service'; -import { LinkService } from '../../../services/link.service'; -import { NodesDataSource } from '../../datasources/nodes-datasource'; -import { LinksDataSource } from '../../datasources/links-datasource'; -import { SelectionManager } from '../../managers/selection-manager'; -import { FontFixer } from '../../helpers/font-fixer'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { MockedLinkService } from '../../../components/project-map/project-map.component.spec'; +import { LinkService } from '../../../services/link.service'; +import { MapScaleService } from '../../../services/mapScale.service'; +import { ToolsService } from '../../../services/tools.service'; +import { LinksDataSource } from '../../datasources/links-datasource'; +import { NodesDataSource } from '../../datasources/nodes-datasource'; +import { DrawingsEventSource } from '../../events/drawings-event-source'; +import { FontFixer } from '../../helpers/font-fixer'; +import { SelectionManager } from '../../managers/selection-manager'; +import { Context } from '../../models/context'; +import { TextEditorComponent } from './text-editor.component'; describe('TextEditorComponent', () => { let component: TextEditorComponent; @@ -31,9 +31,9 @@ describe('TextEditorComponent', () => { { provide: NodesDataSource, useClass: NodesDataSource }, { provide: LinksDataSource, useClass: LinksDataSource }, { provide: SelectionManager, useClass: SelectionManager }, - { provide: FontFixer, useClass: FontFixer } + { provide: FontFixer, useClass: FontFixer }, ], - declarations: [TextEditorComponent] + declarations: [TextEditorComponent], }).compileComponents(); })); diff --git a/src/app/cartography/components/text-editor/text-editor.component.ts b/src/app/cartography/components/text-editor/text-editor.component.ts index e98cea56..aed89350 100644 --- a/src/app/cartography/components/text-editor/text-editor.component.ts +++ b/src/app/cartography/components/text-editor/text-editor.component.ts @@ -1,30 +1,38 @@ -import { Component, ViewChild, ElementRef, OnInit, Input, EventEmitter, OnDestroy, Renderer2, NgZone } from '@angular/core'; +import { + Component, + ElementRef, + EventEmitter, + Input, + NgZone, + OnDestroy, + OnInit, + Renderer2, + ViewChild, +} from '@angular/core'; +import { select } from 'd3-selection'; +import { Subscription } from 'rxjs'; +import { StyleProperty } from '../../../components/project-map/drawings-editors/text-editor/text-editor.component'; +import { Link } from '../../../models/link'; +import { Server } from '../../../models/server'; +import { LinkService } from '../../../services/link.service'; +import { MapScaleService } from '../../../services/mapScale.service'; +import { ToolsService } from '../../../services/tools.service'; +import { LinksDataSource } from '../../datasources/links-datasource'; +import { NodesDataSource } from '../../datasources/nodes-datasource'; import { DrawingsEventSource } from '../../events/drawings-event-source'; import { TextAddedDataEvent, TextEditedDataEvent } from '../../events/event-source'; -import { ToolsService } from '../../../services/tools.service'; -import { select } from 'd3-selection'; -import { TextElement } from '../../models/drawings/text-element'; -import { Context } from '../../models/context'; -import { Subscription } from 'rxjs'; -import { MapScaleService } from '../../../services/mapScale.service'; -import { MapLabel } from '../../models/map/map-label'; -import { MapNode } from '../../models/map/map-node'; -import { NodesDataSource } from '../../datasources/nodes-datasource'; -import { Node } from '../../models/node'; -import { SelectionManager } from '../../managers/selection-manager'; -import { Server } from '../../../models/server'; -import { MapLinkNode } from '../../models/map/map-link-node'; -import { LinkService } from '../../../services/link.service'; -import { LinksDataSource } from '../../datasources/links-datasource'; -import { Link } from '../../../models/link'; -import { StyleProperty } from '../../../components/project-map/drawings-editors/text-editor/text-editor.component'; import { FontFixer } from '../../helpers/font-fixer'; +import { SelectionManager } from '../../managers/selection-manager'; +import { Context } from '../../models/context'; +import { TextElement } from '../../models/drawings/text-element'; import { Font } from '../../models/font'; +import { MapLinkNode } from '../../models/map/map-link-node'; +import { Node } from '../../models/node'; @Component({ selector: 'app-text-editor', templateUrl: './text-editor.component.html', - styleUrls: ['./text-editor.component.scss'] + styleUrls: ['./text-editor.component.scss'], }) export class TextEditorComponent implements OnInit, OnDestroy { @ViewChild('temporaryTextElement') temporaryTextElement: ElementRef; @@ -73,7 +81,11 @@ export class TextEditorComponent implements OnInit, OnDestroy { this.leftPosition = event.pageX.toString() + 'px'; this.topPosition = event.pageY.toString() + 'px'; this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial'); - this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'transform', `scale(${this.mapScaleService.getScale()})`); + this.renderer.setStyle( + this.temporaryTextElement.nativeElement, + 'transform', + `scale(${this.mapScaleService.getScale()})` + ); this.temporaryTextElement.nativeElement.focus(); let textListener = () => { @@ -113,7 +125,11 @@ export class TextEditorComponent implements OnInit, OnDestroy { this.selectionManager.setSelected([]); this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial'); - this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'transform', `scale(${this.mapScaleService.getScale()})`); + this.renderer.setStyle( + this.temporaryTextElement.nativeElement, + 'transform', + `scale(${this.mapScaleService.getScale()})` + ); this.editedLink = elem; select(textElements[index]).attr('visibility', 'hidden'); @@ -121,34 +137,52 @@ export class TextEditorComponent implements OnInit, OnDestroy { this.editedNode = this.nodesDataSource.get(elem.nodeId); this.editedLink = elem; - let x = ((elem.label.originalX + this.editedNode.x - 1) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x; - let y = ((elem.label.originalY + this.editedNode.y + 4) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y; + let x = + (elem.label.originalX + this.editedNode.x - 1) * this.context.transformation.k + + this.context.getZeroZeroTransformationPoint().x + + this.context.transformation.x; + let y = + (elem.label.originalY + this.editedNode.y + 4) * this.context.transformation.k + + this.context.getZeroZeroTransformationPoint().y + + this.context.transformation.y; this.leftPosition = x.toString() + 'px'; this.topPosition = y.toString() + 'px'; this.temporaryTextElement.nativeElement.innerText = elem.label.text; let styleProperties: StyleProperty[] = []; - for (let property of elem.label.style.split(";")){ + for (let property of elem.label.style.split(';')) { styleProperties.push({ - property: property.split(": ")[0], - value: property.split(": ")[1] + property: property.split(': ')[0], + value: property.split(': ')[1], }); } let font: Font = { - font_family: styleProperties.find(p => p.property === 'font-family') ? styleProperties.find(p => p.property === 'font-family').value : 'TypeWriter', - font_size: styleProperties.find(p => p.property === 'font-size') ? Number(styleProperties.find(p => p.property === 'font-size').value) : 10.0, - font_weight: styleProperties.find(p => p.property === 'font-weight') ? styleProperties.find(p => p.property === 'font-weight').value : 'normal' + font_family: styleProperties.find((p) => p.property === 'font-family') + ? styleProperties.find((p) => p.property === 'font-family').value + : 'TypeWriter', + font_size: styleProperties.find((p) => p.property === 'font-size') + ? Number(styleProperties.find((p) => p.property === 'font-size').value) + : 10.0, + font_weight: styleProperties.find((p) => p.property === 'font-weight') + ? styleProperties.find((p) => p.property === 'font-weight').value + : 'normal', }; font = this.fontFixer.fix(font); - this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'color', styleProperties.find(p => p.property === 'fill') ? styleProperties.find(p => p.property === 'fill').value : '#000000'); + this.renderer.setStyle( + this.temporaryTextElement.nativeElement, + 'color', + styleProperties.find((p) => p.property === 'fill') + ? styleProperties.find((p) => p.property === 'fill').value + : '#000000' + ); this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', font.font_family); this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', `${font.font_size}pt`); this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', font.font_weight); - + let listener = () => { let innerText = this.temporaryTextElement.nativeElement.innerText; 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.server, link).subscribe((link: Link) => { rootElement @@ -177,7 +211,11 @@ export class TextEditorComponent implements OnInit, OnDestroy { .selectAll('text.text_element') .on('dblclick', (elem, index, textElements) => { this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial'); - this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'transform', `scale(${this.mapScaleService.getScale()})`); + this.renderer.setStyle( + this.temporaryTextElement.nativeElement, + 'transform', + `scale(${this.mapScaleService.getScale()})` + ); this.editedElement = elem; select(textElements[index]).attr('visibility', 'hidden'); @@ -185,8 +223,14 @@ export class TextEditorComponent implements OnInit, OnDestroy { this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute('drawing_id'); var transformData = textElements[index].parentElement.getAttribute('transform').split(/\(|\)/); - var x = (Number(transformData[1].split(/,/)[0]) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x; - var y = (Number(transformData[1].split(/,/)[1]) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y; + var x = + Number(transformData[1].split(/,/)[0]) * this.context.transformation.k + + this.context.getZeroZeroTransformationPoint().x + + this.context.transformation.x; + var y = + Number(transformData[1].split(/,/)[1]) * this.context.transformation.k + + this.context.getZeroZeroTransformationPoint().y + + this.context.transformation.y; this.leftPosition = x.toString() + 'px'; this.topPosition = y.toString() + 'px'; this.temporaryTextElement.nativeElement.innerText = elem.text; diff --git a/src/app/cartography/converters/map/drawing-to-map-drawing-converter.ts b/src/app/cartography/converters/map/drawing-to-map-drawing-converter.ts index a45ebd29..52713816 100644 --- a/src/app/cartography/converters/map/drawing-to-map-drawing-converter.ts +++ b/src/app/cartography/converters/map/drawing-to-map-drawing-converter.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; import { Drawing } from '../../models/drawing'; import { MapDrawing } from '../../models/map/map-drawing'; +import { Converter } from '../converter'; @Injectable() export class DrawingToMapDrawingConverter implements Converter { diff --git a/src/app/cartography/converters/map/label-to-map-label-converter.ts b/src/app/cartography/converters/map/label-to-map-label-converter.ts index 0d1f0095..8214f2b8 100644 --- a/src/app/cartography/converters/map/label-to-map-label-converter.ts +++ b/src/app/cartography/converters/map/label-to-map-label-converter.ts @@ -1,11 +1,10 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; +import { CssFixer } from '../../helpers/css-fixer'; +import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator'; +import { FontFixer } from '../../helpers/font-fixer'; import { Label } from '../../models/label'; import { MapLabel } from '../../models/map/map-label'; -import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator'; -import { CssFixer } from '../../helpers/css-fixer'; -import { FontFixer } from '../../helpers/font-fixer'; +import { Converter } from '../converter'; @Injectable() export class LabelToMapLabelConverter implements Converter { diff --git a/src/app/cartography/converters/map/link-node-to-map-link-node-converter.ts b/src/app/cartography/converters/map/link-node-to-map-link-node-converter.ts index 66039723..98a857a3 100644 --- a/src/app/cartography/converters/map/link-node-to-map-link-node-converter.ts +++ b/src/app/cartography/converters/map/link-node-to-map-link-node-converter.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; -import { LabelToMapLabelConverter } from './label-to-map-label-converter'; import { LinkNode } from '../../../models/link-node'; import { MapLinkNode } from '../../models/map/map-link-node'; +import { Converter } from '../converter'; +import { LabelToMapLabelConverter } from './label-to-map-label-converter'; @Injectable() export class LinkNodeToMapLinkNodeConverter implements Converter { diff --git a/src/app/cartography/converters/map/link-to-map-link-converter.ts b/src/app/cartography/converters/map/link-to-map-link-converter.ts index b9afd052..28ecf2c8 100644 --- a/src/app/cartography/converters/map/link-to-map-link-converter.ts +++ b/src/app/cartography/converters/map/link-to-map-link-converter.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; -import { LinkNodeToMapLinkNodeConverter } from './link-node-to-map-link-node-converter'; import { Link } from '../../../models/link'; import { MapLink } from '../../models/map/map-link'; +import { Converter } from '../converter'; +import { LinkNodeToMapLinkNodeConverter } from './link-node-to-map-link-node-converter'; @Injectable() export class LinkToMapLinkConverter implements Converter { @@ -17,7 +16,9 @@ export class LinkToMapLinkConverter implements Converter { mapLink.capturing = link.capturing; mapLink.filters = link.filters; mapLink.linkType = link.link_type; - mapLink.nodes = link.nodes.map(linkNode => this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id })); + mapLink.nodes = link.nodes.map((linkNode) => + this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id }) + ); mapLink.projectId = link.project_id; mapLink.suspend = link.suspend; return mapLink; diff --git a/src/app/cartography/converters/map/map-drawing-to-drawing-converter.ts b/src/app/cartography/converters/map/map-drawing-to-drawing-converter.ts index 88ee6c59..aa8a6c42 100644 --- a/src/app/cartography/converters/map/map-drawing-to-drawing-converter.ts +++ b/src/app/cartography/converters/map/map-drawing-to-drawing-converter.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; import { Drawing } from '../../models/drawing'; import { MapDrawing } from '../../models/map/map-drawing'; +import { Converter } from '../converter'; @Injectable() export class MapDrawingToDrawingConverter implements Converter { diff --git a/src/app/cartography/converters/map/map-drawing-to-svg-converter.ts b/src/app/cartography/converters/map/map-drawing-to-svg-converter.ts index cc1cb9b4..e5466483 100644 --- a/src/app/cartography/converters/map/map-drawing-to-svg-converter.ts +++ b/src/app/cartography/converters/map/map-drawing-to-svg-converter.ts @@ -1,11 +1,10 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; -import { MapDrawing } from '../../models/map/map-drawing'; -import { RectElement } from '../../models/drawings/rect-element'; import { EllipseElement } from '../../models/drawings/ellipse-element'; import { LineElement } from '../../models/drawings/line-element'; +import { RectElement } from '../../models/drawings/rect-element'; import { TextElement } from '../../models/drawings/text-element'; +import { MapDrawing } from '../../models/map/map-drawing'; +import { Converter } from '../converter'; @Injectable() export class MapDrawingToSvgConverter implements Converter { @@ -15,27 +14,13 @@ export class MapDrawingToSvgConverter implements Converter { let elem = ``; if (mapDrawing.element instanceof RectElement) { - elem = ``; + elem = ``; } else if (mapDrawing.element instanceof EllipseElement) { - elem = ``; + elem = ``; } else if (mapDrawing.element instanceof LineElement) { - elem = ``; + elem = ``; } else if (mapDrawing.element instanceof TextElement) { - elem = `${ - mapDrawing.element.text - }`; + elem = `${mapDrawing.element.text}`; } else return ''; return `${elem}`; diff --git a/src/app/cartography/converters/map/map-label-to-label-converter.ts b/src/app/cartography/converters/map/map-label-to-label-converter.ts index d6aea518..bc3b0865 100644 --- a/src/app/cartography/converters/map/map-label-to-label-converter.ts +++ b/src/app/cartography/converters/map/map-label-to-label-converter.ts @@ -1,11 +1,10 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; +import { CssFixer } from '../../helpers/css-fixer'; +import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator'; +import { FontFixer } from '../../helpers/font-fixer'; import { Label } from '../../models/label'; import { MapLabel } from '../../models/map/map-label'; -import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator'; -import { CssFixer } from '../../helpers/css-fixer'; -import { FontFixer } from '../../helpers/font-fixer'; +import { Converter } from '../converter'; @Injectable() export class MapLabelToLabelConverter implements Converter { diff --git a/src/app/cartography/converters/map/map-link-node-to-link-node-converter.ts b/src/app/cartography/converters/map/map-link-node-to-link-node-converter.ts index 7e2f739f..f8087278 100644 --- a/src/app/cartography/converters/map/map-link-node-to-link-node-converter.ts +++ b/src/app/cartography/converters/map/map-link-node-to-link-node-converter.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; -import { MapLinkNode } from '../../models/map/map-link-node'; -import { MapLabelToLabelConverter } from './map-label-to-label-converter'; import { LinkNode } from '../../../models/link-node'; +import { MapLinkNode } from '../../models/map/map-link-node'; +import { Converter } from '../converter'; +import { MapLabelToLabelConverter } from './map-label-to-label-converter'; @Injectable() export class MapLinkNodeToLinkNodeConverter implements Converter { diff --git a/src/app/cartography/converters/map/map-link-to-link-converter.ts b/src/app/cartography/converters/map/map-link-to-link-converter.ts index 857ac394..ae269a42 100644 --- a/src/app/cartography/converters/map/map-link-to-link-converter.ts +++ b/src/app/cartography/converters/map/map-link-to-link-converter.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; -import { MapLinkNodeToLinkNodeConverter } from './map-link-node-to-link-node-converter'; import { Link } from '../../../models/link'; import { MapLink } from '../../models/map/map-link'; +import { Converter } from '../converter'; +import { MapLinkNodeToLinkNodeConverter } from './map-link-node-to-link-node-converter'; @Injectable() export class MapLinkToLinkConverter implements Converter { @@ -17,7 +16,7 @@ export class MapLinkToLinkConverter implements Converter { link.capturing = mapLink.capturing; link.filters = mapLink.filters; link.link_type = mapLink.linkType; - 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.suspend = mapLink.suspend; return link; diff --git a/src/app/cartography/converters/map/map-node-to-node-converter.ts b/src/app/cartography/converters/map/map-node-to-node-converter.ts index ae8be713..072bfee2 100644 --- a/src/app/cartography/converters/map/map-node-to-node-converter.ts +++ b/src/app/cartography/converters/map/map-node-to-node-converter.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; import { MapNode } from '../../models/map/map-node'; +import { Node } from '../../models/node'; +import { Converter } from '../converter'; import { MapLabelToLabelConverter } from './map-label-to-label-converter'; import { MapPortToPortConverter } from './map-port-to-port-converter'; -import { Node } from '../../models/node'; @Injectable() export class MapNodeToNodeConverter implements Converter { @@ -27,7 +26,7 @@ export class MapNodeToNodeConverter implements Converter { node.node_type = mapNode.nodeType; node.port_name_format = mapNode.portNameFormat; node.port_segment_size = mapNode.portSegmentSize; - node.ports = mapNode.ports ? mapNode.ports.map(mapPort => this.mapPortToPort.convert(mapPort)) : []; + node.ports = mapNode.ports ? mapNode.ports.map((mapPort) => this.mapPortToPort.convert(mapPort)) : []; node.project_id = mapNode.projectId; node.status = mapNode.status; node.symbol = mapNode.symbol; diff --git a/src/app/cartography/converters/map/map-port-to-port-converter.ts b/src/app/cartography/converters/map/map-port-to-port-converter.ts index aecd4fde..464985f4 100644 --- a/src/app/cartography/converters/map/map-port-to-port-converter.ts +++ b/src/app/cartography/converters/map/map-port-to-port-converter.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; import { Port } from '../../../models/port'; import { MapPort } from '../../models/map/map-port'; +import { Converter } from '../converter'; @Injectable() export class MapPortToPortConverter implements Converter { diff --git a/src/app/cartography/converters/map/map-symbol-to-symbol-converter.ts b/src/app/cartography/converters/map/map-symbol-to-symbol-converter.ts index 9503e80b..5e95e61c 100644 --- a/src/app/cartography/converters/map/map-symbol-to-symbol-converter.ts +++ b/src/app/cartography/converters/map/map-symbol-to-symbol-converter.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; -import { MapSymbol } from '../../models/map/map-symbol'; import { Symbol } from '../../../models/symbol'; +import { MapSymbol } from '../../models/map/map-symbol'; +import { Converter } from '../converter'; @Injectable() export class MapSymbolToSymbolConverter implements Converter { diff --git a/src/app/cartography/converters/map/node-to-map-node-converter.ts b/src/app/cartography/converters/map/node-to-map-node-converter.ts index 4608082b..b31e4b84 100644 --- a/src/app/cartography/converters/map/node-to-map-node-converter.ts +++ b/src/app/cartography/converters/map/node-to-map-node-converter.ts @@ -1,13 +1,12 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; +import { CssFixer } from '../../helpers/css-fixer'; +import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator'; +import { FontFixer } from '../../helpers/font-fixer'; import { MapNode } from '../../models/map/map-node'; import { Node } from '../../models/node'; +import { Converter } from '../converter'; import { LabelToMapLabelConverter } from './label-to-map-label-converter'; import { PortToMapPortConverter } from './port-to-map-port-converter'; -import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator'; -import { CssFixer } from '../../helpers/css-fixer'; -import { FontFixer } from '../../helpers/font-fixer'; @Injectable() export class NodeToMapNodeConverter implements Converter { @@ -29,14 +28,16 @@ export class NodeToMapNodeConverter implements Converter { mapNode.consoleType = node.console_type; mapNode.firstPortName = node.first_port_name; mapNode.height = node.height; - mapNode.label = this.labelToMapLabel ? this.labelToMapLabel.convert(node.label, { node_id: node.node_id }) : undefined; + mapNode.label = this.labelToMapLabel + ? this.labelToMapLabel.convert(node.label, { node_id: node.node_id }) + : undefined; mapNode.locked = node.locked; mapNode.name = node.name; mapNode.nodeDirectory = node.node_directory; mapNode.nodeType = node.node_type; mapNode.portNameFormat = node.port_name_format; mapNode.portSegmentSize = node.port_segment_size; - mapNode.ports = node.ports ? node.ports.map(port => this.portToMapPort.convert(port)) : []; + mapNode.ports = node.ports ? node.ports.map((port) => this.portToMapPort.convert(port)) : []; mapNode.projectId = node.project_id; mapNode.status = node.status; mapNode.symbol = node.symbol; diff --git a/src/app/cartography/converters/map/port-to-map-port-converter.ts b/src/app/cartography/converters/map/port-to-map-port-converter.ts index 8a348ae1..efbdc253 100644 --- a/src/app/cartography/converters/map/port-to-map-port-converter.ts +++ b/src/app/cartography/converters/map/port-to-map-port-converter.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; import { Port } from '../../../models/port'; import { MapPort } from '../../models/map/map-port'; +import { Converter } from '../converter'; @Injectable() export class PortToMapPortConverter implements Converter { diff --git a/src/app/cartography/converters/map/symbol-to-map-symbol-converter.ts b/src/app/cartography/converters/map/symbol-to-map-symbol-converter.ts index 46f1077d..011c0571 100644 --- a/src/app/cartography/converters/map/symbol-to-map-symbol-converter.ts +++ b/src/app/cartography/converters/map/symbol-to-map-symbol-converter.ts @@ -1,8 +1,7 @@ import { Injectable } from '@angular/core'; - -import { Converter } from '../converter'; import { Symbol } from '../../../models/symbol'; import { MapSymbol } from '../../models/map/map-symbol'; +import { Converter } from '../converter'; @Injectable() export class SymbolToMapSymbolConverter implements Converter { diff --git a/src/app/cartography/converters/styles-to-font-converter.spec.ts b/src/app/cartography/converters/styles-to-font-converter.spec.ts index 8726a6b1..2283dc98 100644 --- a/src/app/cartography/converters/styles-to-font-converter.spec.ts +++ b/src/app/cartography/converters/styles-to-font-converter.spec.ts @@ -14,7 +14,7 @@ describe('StylesToFontConverter', () => { const expectedFont: Font = { font_family: 'TypeWriter', font_size: 10, - font_weight: 'bold' + font_weight: 'bold', }; expect(converter.convert(styles)).toEqual(expectedFont); diff --git a/src/app/cartography/converters/styles-to-font-converter.ts b/src/app/cartography/converters/styles-to-font-converter.ts index 9fa1e5e6..3c699151 100644 --- a/src/app/cartography/converters/styles-to-font-converter.ts +++ b/src/app/cartography/converters/styles-to-font-converter.ts @@ -1,8 +1,7 @@ -import * as csstree from 'css-tree'; - import { Injectable } from '@angular/core'; -import { Converter } from './converter'; +import * as csstree from 'css-tree'; import { Font } from '../models/font'; +import { Converter } from './converter'; @Injectable() export class StylesToFontConverter implements Converter { @@ -10,30 +9,30 @@ export class StylesToFontConverter implements Converter { const font: Font = { font_family: undefined, font_size: undefined, - font_weight: undefined + font_weight: undefined, }; const ast = csstree.parse(styles, { - context: 'declarationList' + context: 'declarationList', }); - ast.children.forEach(child => { + ast.children.forEach((child) => { if (child.property === 'font-size' && child.value && child.value.children) { - child.value.children.forEach(value => { + child.value.children.forEach((value) => { if (value.type === 'Dimension') { font.font_size = parseInt(value.value); } }); } if (child.property === 'font-family' && child.value && child.value.children) { - child.value.children.forEach(value => { + child.value.children.forEach((value) => { if (value.type === 'Identifier') { font.font_family = value.name; } }); } if (child.property === 'font-weight' && child.value && child.value.children) { - child.value.children.forEach(value => { + child.value.children.forEach((value) => { if (value.type === 'Identifier') { font.font_weight = value.name; } diff --git a/src/app/cartography/d3-map.imports.ts b/src/app/cartography/d3-map.imports.ts index ee956b81..2c35abaa 100644 --- a/src/app/cartography/d3-map.imports.ts +++ b/src/app/cartography/d3-map.imports.ts @@ -1,22 +1,22 @@ -import { GraphLayout } from './widgets/graph-layout'; -import { LinksWidget } from './widgets/links'; -import { NodesWidget } from './widgets/nodes'; -import { DrawingsWidget } from './widgets/drawings'; -import { DrawingLineWidget } from './widgets/drawing-line'; -import { SelectionTool } from './tools/selection-tool'; import { MovingTool } from './tools/moving-tool'; -import { LayersWidget } from './widgets/layers'; -import { LinkWidget } from './widgets/link'; -import { InterfaceStatusWidget } from './widgets/interface-status'; -import { InterfaceLabelWidget } from './widgets/interface-label'; +import { SelectionTool } from './tools/selection-tool'; +import { DrawingWidget } from './widgets/drawing'; +import { DrawingLineWidget } from './widgets/drawing-line'; +import { DrawingsWidget } from './widgets/drawings'; import { EllipseDrawingWidget } from './widgets/drawings/ellipse-drawing'; import { ImageDrawingWidget } from './widgets/drawings/image-drawing'; +import { LineDrawingWidget } from './widgets/drawings/line-drawing'; import { RectDrawingWidget } from './widgets/drawings/rect-drawing'; import { TextDrawingWidget } from './widgets/drawings/text-drawing'; -import { LineDrawingWidget } from './widgets/drawings/line-drawing'; -import { NodeWidget } from './widgets/node'; -import { DrawingWidget } from './widgets/drawing'; +import { GraphLayout } from './widgets/graph-layout'; +import { InterfaceLabelWidget } from './widgets/interface-label'; +import { InterfaceStatusWidget } from './widgets/interface-status'; import { LabelWidget } from './widgets/label'; +import { LayersWidget } from './widgets/layers'; +import { LinkWidget } from './widgets/link'; +import { LinksWidget } from './widgets/links'; +import { NodeWidget } from './widgets/node'; +import { NodesWidget } from './widgets/nodes'; export const D3_MAP_IMPORTS = [ GraphLayout, @@ -37,5 +37,5 @@ export const D3_MAP_IMPORTS = [ LineDrawingWidget, RectDrawingWidget, TextDrawingWidget, - DrawingWidget + DrawingWidget, ]; diff --git a/src/app/cartography/datasources/datasource.ts b/src/app/cartography/datasources/datasource.ts index ce5aaf06..e4f1275c 100644 --- a/src/app/cartography/datasources/datasource.ts +++ b/src/app/cartography/datasources/datasource.ts @@ -20,7 +20,7 @@ export abstract class DataSource { } public set(data: T[]) { - data.forEach(item => { + data.forEach((item) => { const index = this.findIndex(item); if (index >= 0) { const updated = Object.assign(this.data[index], item); @@ -31,9 +31,9 @@ export abstract class DataSource { }); const toRemove = this.data.filter( - item => data.filter(i => this.getItemKey(i) === this.getItemKey(item)).length === 0 + (item) => data.filter((i) => this.getItemKey(i) === this.getItemKey(item)).length === 0 ); - toRemove.forEach(item => this.remove(item)); + toRemove.forEach((item) => this.remove(item)); this.dataChange.next(this.data); } diff --git a/src/app/cartography/datasources/drawings-datasource.spec.ts b/src/app/cartography/datasources/drawings-datasource.spec.ts index 9404dfd6..ccdbc539 100644 --- a/src/app/cartography/datasources/drawings-datasource.spec.ts +++ b/src/app/cartography/datasources/drawings-datasource.spec.ts @@ -1,5 +1,5 @@ -import { DrawingsDataSource } from './drawings-datasource'; import { Drawing } from '../models/drawing'; +import { DrawingsDataSource } from './drawings-datasource'; describe('DrawingsDataSource', () => { let dataSource: DrawingsDataSource; diff --git a/src/app/cartography/datasources/drawings-datasource.ts b/src/app/cartography/datasources/drawings-datasource.ts index a5f4c67f..bf9f5eb0 100644 --- a/src/app/cartography/datasources/drawings-datasource.ts +++ b/src/app/cartography/datasources/drawings-datasource.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; - -import { DataSource } from './datasource'; import { Drawing } from '../models/drawing'; +import { DataSource } from './datasource'; @Injectable() export class DrawingsDataSource extends DataSource { diff --git a/src/app/cartography/datasources/links-datasource.spec.ts b/src/app/cartography/datasources/links-datasource.spec.ts index 107f49e6..99675e9e 100644 --- a/src/app/cartography/datasources/links-datasource.spec.ts +++ b/src/app/cartography/datasources/links-datasource.spec.ts @@ -1,5 +1,5 @@ -import { LinksDataSource } from './links-datasource'; import { Link } from '../../models/link'; +import { LinksDataSource } from './links-datasource'; describe('LinksDataSource', () => { let dataSource: LinksDataSource; diff --git a/src/app/cartography/datasources/links-datasource.ts b/src/app/cartography/datasources/links-datasource.ts index ee626e19..a60e3fba 100644 --- a/src/app/cartography/datasources/links-datasource.ts +++ b/src/app/cartography/datasources/links-datasource.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; - -import { DataSource } from './datasource'; import { Link } from '../../models/link'; +import { DataSource } from './datasource'; @Injectable() export class LinksDataSource extends DataSource { diff --git a/src/app/cartography/datasources/map-datasource.ts b/src/app/cartography/datasources/map-datasource.ts index 8fbe3466..4a42ee8f 100644 --- a/src/app/cartography/datasources/map-datasource.ts +++ b/src/app/cartography/datasources/map-datasource.ts @@ -1,9 +1,9 @@ -import { DataSource } from './datasource'; -import { MapNode } from '../models/map/map-node'; -import { MapLink } from '../models/map/map-link'; -import { MapDrawing } from '../models/map/map-drawing'; -import { MapSymbol } from '../models/map/map-symbol'; import { Injectable } from '@angular/core'; +import { MapDrawing } from '../models/map/map-drawing'; +import { MapLink } from '../models/map/map-link'; +import { MapNode } from '../models/map/map-node'; +import { MapSymbol } from '../models/map/map-symbol'; +import { DataSource } from './datasource'; export interface Indexed { id: number | string; diff --git a/src/app/cartography/datasources/nodes-datasource.spec.ts b/src/app/cartography/datasources/nodes-datasource.spec.ts index f0f87fee..4c3278d3 100644 --- a/src/app/cartography/datasources/nodes-datasource.spec.ts +++ b/src/app/cartography/datasources/nodes-datasource.spec.ts @@ -1,5 +1,5 @@ -import { NodesDataSource } from './nodes-datasource'; import { Node } from '../models/node'; +import { NodesDataSource } from './nodes-datasource'; describe('NodesDataSource', () => { let dataSource: NodesDataSource; diff --git a/src/app/cartography/datasources/nodes-datasource.ts b/src/app/cartography/datasources/nodes-datasource.ts index d6277283..a3230830 100644 --- a/src/app/cartography/datasources/nodes-datasource.ts +++ b/src/app/cartography/datasources/nodes-datasource.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; - import { Node } from '../models/node'; import { DataSource } from './datasource'; diff --git a/src/app/cartography/datasources/symbols-datasource.spec.ts b/src/app/cartography/datasources/symbols-datasource.spec.ts index f9d3d461..124e7d1e 100644 --- a/src/app/cartography/datasources/symbols-datasource.spec.ts +++ b/src/app/cartography/datasources/symbols-datasource.spec.ts @@ -1,5 +1,5 @@ -import { SymbolsDataSource } from './symbols-datasource'; import { Symbol } from '../../models/symbol'; +import { SymbolsDataSource } from './symbols-datasource'; describe('SymbolsDataSource', () => { let dataSource: SymbolsDataSource; diff --git a/src/app/cartography/datasources/symbols-datasource.ts b/src/app/cartography/datasources/symbols-datasource.ts index 599b5eb5..36f7225e 100644 --- a/src/app/cartography/datasources/symbols-datasource.ts +++ b/src/app/cartography/datasources/symbols-datasource.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; - -import { DataSource } from './datasource'; import { Symbol } from '../../models/symbol'; +import { DataSource } from './datasource'; @Injectable() export class SymbolsDataSource extends DataSource { diff --git a/src/app/cartography/directives/moving-canvas.directive.spec.ts b/src/app/cartography/directives/moving-canvas.directive.spec.ts index 1813c8c4..0a9cda7d 100644 --- a/src/app/cartography/directives/moving-canvas.directive.spec.ts +++ b/src/app/cartography/directives/moving-canvas.directive.spec.ts @@ -1,169 +1,193 @@ -import { ComponentFixture, TestBed, async, tick, fakeAsync } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Context } from '../models/context'; -import { MovingEventSource } from '../events/moving-event-source'; -import { MovingCanvasDirective } from './moving-canvas.directive'; import { Component } from '@angular/core'; +import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { MovingEventSource } from '../events/moving-event-source'; +import { Context } from '../models/context'; +import { MovingCanvasDirective } from './moving-canvas.directive'; @Component({ - template: `` + template: ` + + `, }) class DummyComponent { - constructor(){} + constructor() {} } describe('MovingCanvasDirective', () => { - let component: DummyComponent; - let fixture: ComponentFixture; - let movingEventSource = new MovingEventSource(); + let component: DummyComponent; + let fixture: ComponentFixture; + let movingEventSource = new MovingEventSource(); - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [NoopAnimationsModule], - providers: [ - { provide: MovingEventSource, useValue: movingEventSource }, - { provide: Context, useClass: Context } - ], - declarations: [DummyComponent, MovingCanvasDirective] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(DummyComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [NoopAnimationsModule], + providers: [ + { provide: MovingEventSource, useValue: movingEventSource }, + { provide: Context, useClass: Context }, + ], + declarations: [DummyComponent, MovingCanvasDirective], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DummyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should move canvas if moving mode is activated', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let xMovement: number = 200; - let yMovement: number = 200; + it('should create', () => { + expect(component).toBeTruthy(); + }); - canvas.dispatchEvent(new MouseEvent('mousedown', { - bubbles: true, - clientX: 0, - clientY: 0, - screenY: 0, - screenX: 0, - view: window - })); - tick(); - canvas.dispatchEvent(new MouseEvent('mousemove', { - bubbles: true, - relatedTarget: canvas, - movementX: xMovement, - movementY: yMovement - } as MouseEventInit)); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); - })); + it('should move canvas if moving mode is activated', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let xMovement: number = 200; + let yMovement: number = 200; - it('should not move canvas if moving mode is not activated', fakeAsync(() => { - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + canvas.dispatchEvent( + new MouseEvent('mousedown', { + bubbles: true, + clientX: 0, + clientY: 0, + screenY: 0, + screenX: 0, + view: window, + }) + ); + tick(); + canvas.dispatchEvent( + new MouseEvent('mousemove', { + bubbles: true, + relatedTarget: canvas, + movementX: xMovement, + movementY: yMovement, + } as MouseEventInit) + ); + tick(); - canvas.dispatchEvent(new MouseEvent('mousedown', { - bubbles: true, - clientX: 0, - clientY: 0, - screenY: 0, - screenX: 0, - view: window - })); - tick(); - canvas.dispatchEvent(new MouseEvent('mousemove', { - bubbles: true, - relatedTarget: canvas, - movementX: 1000, - movementY: 1000 - } as MouseEventInit)); - tick(); - - expect(canvas.getAttribute('transform')).toEqual('translate(0, 0) scale(1)'); - })); + expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); + })); - it('should not move canvas after mouseup event', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let xMovement: number = 200; - let yMovement: number = 200; + it('should not move canvas if moving mode is not activated', fakeAsync(() => { + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - canvas.dispatchEvent(new MouseEvent('mousedown', { - bubbles: true, - clientX: 0, - clientY: 0, - screenY: 0, - screenX: 0, - view: window - })); - tick(); - canvas.dispatchEvent(new MouseEvent('mousemove', { - bubbles: true, - relatedTarget: canvas, - movementX: xMovement, - movementY: yMovement - } as MouseEventInit)); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); - - canvas.dispatchEvent(new MouseEvent('mouseup', { - bubbles: true, - relatedTarget: canvas, - movementX: 1000, - movementY: 1000 - } as MouseEventInit)); - tick(); - canvas.dispatchEvent(new MouseEvent('mousemove', { - bubbles: true, - relatedTarget: canvas, - movementX: xMovement, - movementY: yMovement - } as MouseEventInit)); - tick(); + canvas.dispatchEvent( + new MouseEvent('mousedown', { + bubbles: true, + clientX: 0, + clientY: 0, + screenY: 0, + screenX: 0, + view: window, + }) + ); + tick(); + canvas.dispatchEvent( + new MouseEvent('mousemove', { + bubbles: true, + relatedTarget: canvas, + movementX: 1000, + movementY: 1000, + } as MouseEventInit) + ); + tick(); - expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); - })); + expect(canvas.getAttribute('transform')).toEqual('translate(0, 0) scale(1)'); + })); - it('should not move canvas after deactivation of moving mode', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let xMovement: number = 200; - let yMovement: number = 200; + it('should not move canvas after mouseup event', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let xMovement: number = 200; + let yMovement: number = 200; - canvas.dispatchEvent(new MouseEvent('mousedown', { - bubbles: true, - clientX: 0, - clientY: 0, - screenY: 0, - screenX: 0, - view: window - })); - tick(); - canvas.dispatchEvent(new MouseEvent('mousemove', { - bubbles: true, - relatedTarget: canvas, - movementX: xMovement, - movementY: yMovement - } as MouseEventInit)); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); - - movingEventSource.movingModeState.emit(false); - canvas.dispatchEvent(new MouseEvent('mousemove', { - bubbles: true, - relatedTarget: canvas, - movementX: 1000, - movementY: 1000 - } as MouseEventInit)); - tick(); + canvas.dispatchEvent( + new MouseEvent('mousedown', { + bubbles: true, + clientX: 0, + clientY: 0, + screenY: 0, + screenX: 0, + view: window, + }) + ); + tick(); + canvas.dispatchEvent( + new MouseEvent('mousemove', { + bubbles: true, + relatedTarget: canvas, + movementX: xMovement, + movementY: yMovement, + } as MouseEventInit) + ); + tick(); - expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); - })); + expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); + + canvas.dispatchEvent( + new MouseEvent('mouseup', { + bubbles: true, + relatedTarget: canvas, + movementX: 1000, + movementY: 1000, + } as MouseEventInit) + ); + tick(); + canvas.dispatchEvent( + new MouseEvent('mousemove', { + bubbles: true, + relatedTarget: canvas, + movementX: xMovement, + movementY: yMovement, + } as MouseEventInit) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); + })); + + it('should not move canvas after deactivation of moving mode', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let xMovement: number = 200; + let yMovement: number = 200; + + canvas.dispatchEvent( + new MouseEvent('mousedown', { + bubbles: true, + clientX: 0, + clientY: 0, + screenY: 0, + screenX: 0, + view: window, + }) + ); + tick(); + canvas.dispatchEvent( + new MouseEvent('mousemove', { + bubbles: true, + relatedTarget: canvas, + movementX: xMovement, + movementY: yMovement, + } as MouseEventInit) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); + + movingEventSource.movingModeState.emit(false); + canvas.dispatchEvent( + new MouseEvent('mousemove', { + bubbles: true, + relatedTarget: canvas, + movementX: 1000, + movementY: 1000, + } as MouseEventInit) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(${xMovement}, ${yMovement}) scale(1)`); + })); }); diff --git a/src/app/cartography/directives/moving-canvas.directive.ts b/src/app/cartography/directives/moving-canvas.directive.ts index 4fe6c197..d431ea5f 100644 --- a/src/app/cartography/directives/moving-canvas.directive.ts +++ b/src/app/cartography/directives/moving-canvas.directive.ts @@ -1,65 +1,73 @@ -import { HostListener, ElementRef, Directive, Input, OnInit, OnDestroy, Renderer2 } from '@angular/core' +import { Directive, ElementRef, HostListener, OnDestroy, OnInit } from '@angular/core'; +import { select } from 'd3-selection'; import { Subscription } from 'rxjs'; import { MovingEventSource } from '../events/moving-event-source'; import { Context } from '../models/context'; -import { select } from 'd3-selection'; @Directive({ - selector: '[movingCanvas]', + selector: '[movingCanvas]', }) export class MovingCanvasDirective implements OnInit, OnDestroy { - private mouseupListener: Function; - private mousemoveListener: Function; - private movingModeState: Subscription; - private activated: boolean = false; - - constructor( - private element: ElementRef, - private movingEventSource: MovingEventSource, - private context: Context - ) {} + private mouseupListener: Function; + private mousemoveListener: Function; + private movingModeState: Subscription; + private activated: boolean = false; - ngOnInit() { - this.movingModeState = this.movingEventSource.movingModeState.subscribe((event: boolean) => { - this.activated = event; - if (!event) this.removelisteners(); + constructor(private element: ElementRef, private movingEventSource: MovingEventSource, private context: Context) {} + + ngOnInit() { + this.movingModeState = this.movingEventSource.movingModeState.subscribe((event: boolean) => { + this.activated = event; + if (!event) this.removelisteners(); + }); + } + + ngOnDestroy() { + this.movingModeState.unsubscribe(); + } + + @HostListener('mousedown', ['$event']) + onMouseDown(event: MouseEvent) { + if (this.activated) { + this.mousemoveListener = (event: MouseEvent) => { + const view = select(this.element.nativeElement); + const canvas = view.selectAll('g.canvas').data([this.context]); + + canvas.attr('transform', () => { + this.context.transformation.x = this.context.transformation.x + event.movementX; + this.context.transformation.y = this.context.transformation.y + event.movementY; + + const xTrans = this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x; + const yTrans = this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y; + const kTrans = this.context.transformation.k; + + return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`; }); - } + }; - ngOnDestroy() { - this.movingModeState.unsubscribe(); - } + this.mouseupListener = (event: MouseEvent) => { + this.removelisteners(); + }; - @HostListener('mousedown', ['$event']) - onMouseDown(event: MouseEvent) { - if (this.activated) { - this.mousemoveListener = (event: MouseEvent) => { - const view = select(this.element.nativeElement); - const canvas = view.selectAll('g.canvas').data([this.context]); - - canvas.attr('transform', () => { - this.context.transformation.x = this.context.transformation.x + event.movementX; - this.context.transformation.y = this.context.transformation.y + event.movementY; - - const xTrans = this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x; - const yTrans = this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y; - const kTrans = this.context.transformation.k; - - return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`; - }); - }; - - this.mouseupListener = (event: MouseEvent) => { - this.removelisteners(); - }; - - this.element.nativeElement.addEventListener('mouseup', this.mouseupListener as EventListenerOrEventListenerObject); - this.element.nativeElement.addEventListener('mousemove', this.mousemoveListener as EventListenerOrEventListenerObject); - } + this.element.nativeElement.addEventListener( + 'mouseup', + this.mouseupListener as EventListenerOrEventListenerObject + ); + this.element.nativeElement.addEventListener( + 'mousemove', + this.mousemoveListener as EventListenerOrEventListenerObject + ); } + } - removelisteners() { - this.element.nativeElement.removeEventListener('mouseup', this.mouseupListener as EventListenerOrEventListenerObject); - this.element.nativeElement.removeEventListener('mousemove', this.mousemoveListener as EventListenerOrEventListenerObject); - } + removelisteners() { + this.element.nativeElement.removeEventListener( + 'mouseup', + this.mouseupListener as EventListenerOrEventListenerObject + ); + this.element.nativeElement.removeEventListener( + 'mousemove', + this.mousemoveListener as EventListenerOrEventListenerObject + ); + } } diff --git a/src/app/cartography/directives/zooming-canvas.directive.spec.ts b/src/app/cartography/directives/zooming-canvas.directive.spec.ts index 8e84de01..3407eaef 100644 --- a/src/app/cartography/directives/zooming-canvas.directive.spec.ts +++ b/src/app/cartography/directives/zooming-canvas.directive.spec.ts @@ -1,139 +1,151 @@ -import { ComponentFixture, TestBed, async, tick, fakeAsync } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Context } from '../models/context'; -import { MovingEventSource } from '../events/moving-event-source'; import { Component } from '@angular/core'; -import { ZoomingCanvasDirective } from './zooming-canvas.directive'; +import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { MapScaleService } from '../../services/mapScale.service'; +import { MovingEventSource } from '../events/moving-event-source'; +import { Context } from '../models/context'; +import { ZoomingCanvasDirective } from './zooming-canvas.directive'; @Component({ - template: `` + template: ` + + `, }) class DummyComponent { - constructor(){} + constructor() {} } describe('ZoomingCanvasDirective', () => { - let component: DummyComponent; - let fixture: ComponentFixture; - let movingEventSource = new MovingEventSource(); + let component: DummyComponent; + let fixture: ComponentFixture; + let movingEventSource = new MovingEventSource(); - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [NoopAnimationsModule], - providers: [ - { provide: MovingEventSource, useValue: movingEventSource }, - { provide: Context, useClass: Context }, - { provide: MapScaleService, useClass: MapScaleService } - ], - declarations: [DummyComponent, ZoomingCanvasDirective] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(DummyComponent); - component = fixture.componentInstance; - fixture.detectChanges(); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [NoopAnimationsModule], + providers: [ + { provide: MovingEventSource, useValue: movingEventSource }, + { provide: Context, useClass: Context }, + { provide: MapScaleService, useClass: MapScaleService }, + ], + declarations: [DummyComponent, ZoomingCanvasDirective], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DummyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should zoom in canvas if moving mode is activated', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let deltaMode: number = 0; + let zoom: number = -1000; + + canvas.dispatchEvent( + new WheelEvent('wheel', { + bubbles: true, + relatedTarget: canvas, + deltaMode: deltaMode, + deltaY: zoom, + }) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(2)`); + })); + + it('should zoom out canvas if moving mode is activated', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let deltaMode: number = 0; + let zoom: number = 100; + + canvas.dispatchEvent( + new WheelEvent('wheel', { + bubbles: true, + relatedTarget: canvas, + deltaMode: deltaMode, + deltaY: zoom, + }) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(0.9)`); + })); + + it('should not zoom in/out canvas if moving mode is not activated', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let deltaMode: number = 0; + let zoom: number = -1000; + + canvas.dispatchEvent( + new WheelEvent('wheel', { + bubbles: true, + relatedTarget: canvas, + deltaMode: deltaMode, + deltaY: zoom, + }) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(2)`); + + movingEventSource.movingModeState.emit(false); + canvas.dispatchEvent( + new WheelEvent('wheel', { + bubbles: true, + relatedTarget: canvas, + deltaMode: deltaMode, + deltaY: zoom, + }) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(2)`); + })); + + it('should not zoom in/out canvas after deactivation of moving mode', fakeAsync(() => { + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let deltaMode: number = 0; + let zoom: number = -1000; + + canvas.dispatchEvent( + new WheelEvent('wheel', { + bubbles: true, + relatedTarget: canvas, + deltaMode: deltaMode, + deltaY: zoom, + }) + ); + tick(); + + expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(1)`); + })); + + it('should prevent from default wheel behaviour when moving mode activated', fakeAsync(() => { + movingEventSource.movingModeState.emit(true); + const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); + let deltaMode: number = 0; + let zoom: number = -1000; + const event = new WheelEvent('wheel', { + bubbles: true, + relatedTarget: canvas, + deltaMode: deltaMode, + deltaY: zoom, }); + spyOn(event, 'preventDefault'); - it('should create', () => { - expect(component).toBeTruthy(); - }); + canvas.dispatchEvent(event); + tick(); - it('should zoom in canvas if moving mode is activated', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let deltaMode: number = 0; - let zoom: number = -1000; - - canvas.dispatchEvent(new WheelEvent('wheel', { - bubbles: true, - relatedTarget: canvas, - deltaMode: deltaMode, - deltaY: zoom - })); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(2)`); - })); - - it('should zoom out canvas if moving mode is activated', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let deltaMode: number = 0; - let zoom: number = 100; - - canvas.dispatchEvent(new WheelEvent('wheel', { - bubbles: true, - relatedTarget: canvas, - deltaMode: deltaMode, - deltaY: zoom - })); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(0.9)`); - })); - - it('should not zoom in/out canvas if moving mode is not activated', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let deltaMode: number = 0; - let zoom: number = -1000; - - canvas.dispatchEvent(new WheelEvent('wheel', { - bubbles: true, - relatedTarget: canvas, - deltaMode: deltaMode, - deltaY: zoom - })); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(2)`); - - movingEventSource.movingModeState.emit(false); - canvas.dispatchEvent(new WheelEvent('wheel', { - bubbles: true, - relatedTarget: canvas, - deltaMode: deltaMode, - deltaY: zoom - })); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(2)`); - })); - - it('should not zoom in/out canvas after deactivation of moving mode', fakeAsync(() => { - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let deltaMode: number = 0; - let zoom: number = -1000; - - canvas.dispatchEvent(new WheelEvent('wheel', { - bubbles: true, - relatedTarget: canvas, - deltaMode: deltaMode, - deltaY: zoom - })); - tick(); - - expect(canvas.getAttribute('transform')).toEqual(`translate(0, 0) scale(1)`); - })); - - it('should prevent from default wheel behaviour when moving mode activated', fakeAsync(() => { - movingEventSource.movingModeState.emit(true); - const canvas: HTMLElement = fixture.debugElement.nativeElement.querySelector('.canvas'); - let deltaMode: number = 0; - let zoom: number = -1000; - const event = new WheelEvent('wheel', { - bubbles: true, - relatedTarget: canvas, - deltaMode: deltaMode, - deltaY: zoom - }); - spyOn(event, 'preventDefault'); - - canvas.dispatchEvent(event); - tick(); - - expect(event.preventDefault).toHaveBeenCalled(); - })); + expect(event.preventDefault).toHaveBeenCalled(); + })); }); diff --git a/src/app/cartography/directives/zooming-canvas.directive.ts b/src/app/cartography/directives/zooming-canvas.directive.ts index c2b25288..c72bc874 100644 --- a/src/app/cartography/directives/zooming-canvas.directive.ts +++ b/src/app/cartography/directives/zooming-canvas.directive.ts @@ -1,61 +1,63 @@ -import { ElementRef, Directive, OnInit, OnDestroy } from '@angular/core' +import { Directive, ElementRef, OnDestroy, OnInit } from '@angular/core'; +import { select } from 'd3-selection'; import { Subscription } from 'rxjs'; +import { MapScaleService } from '../../services/mapScale.service'; import { MovingEventSource } from '../events/moving-event-source'; import { Context } from '../models/context'; -import { select } from 'd3-selection'; -import { MapScaleService } from '../../services/mapScale.service'; @Directive({ - selector: '[zoomingCanvas]', + selector: '[zoomingCanvas]', }) export class ZoomingCanvasDirective implements OnInit, OnDestroy { - private wheelListener: Function; - private movingModeState: Subscription; - - constructor( - private element: ElementRef, - private movingEventSource: MovingEventSource, - private context: Context, - private mapsScaleService: MapScaleService - ) {} + private wheelListener: Function; + private movingModeState: Subscription; - ngOnInit() { - this.movingModeState = this.movingEventSource.movingModeState.subscribe((event: boolean) => { - event ? this.addListener() : this.removeListener(); - }); - } + constructor( + private element: ElementRef, + private movingEventSource: MovingEventSource, + private context: Context, + private mapsScaleService: MapScaleService + ) {} - ngOnDestroy() { - this.movingModeState.unsubscribe(); - } + ngOnInit() { + this.movingModeState = this.movingEventSource.movingModeState.subscribe((event: boolean) => { + event ? this.addListener() : this.removeListener(); + }); + } - addListener() { - this.wheelListener = (event: WheelEvent) => { - event.stopPropagation(); - event.preventDefault(); + ngOnDestroy() { + this.movingModeState.unsubscribe(); + } - let zoom = event.deltaY; - zoom = event.deltaMode === 0 ? zoom/100 : zoom/3; + addListener() { + this.wheelListener = (event: WheelEvent) => { + event.stopPropagation(); + event.preventDefault(); - const view = select(this.element.nativeElement); - const canvas = view.selectAll('g.canvas').data([this.context]); - - canvas.attr('transform', () => { - this.context.transformation.k = this.context.transformation.k - zoom/10; + let zoom = event.deltaY; + zoom = event.deltaMode === 0 ? zoom / 100 : zoom / 3; - const xTrans = this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x; - const yTrans = this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y; - const kTrans = this.context.transformation.k; - this.mapsScaleService.setScale(kTrans); + const view = select(this.element.nativeElement); + const canvas = view.selectAll('g.canvas').data([this.context]); - return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`; - }); - }; + canvas.attr('transform', () => { + this.context.transformation.k = this.context.transformation.k - zoom / 10; - this.element.nativeElement.addEventListener('wheel', this.wheelListener as EventListenerOrEventListenerObject, {passive: false}); - } + const xTrans = this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x; + const yTrans = this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y; + const kTrans = this.context.transformation.k; + this.mapsScaleService.setScale(kTrans); - removeListener() { - this.element.nativeElement.removeEventListener('wheel', this.wheelListener as EventListenerOrEventListenerObject); - } + return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`; + }); + }; + + this.element.nativeElement.addEventListener('wheel', this.wheelListener as EventListenerOrEventListenerObject, { + passive: false, + }); + } + + removeListener() { + this.element.nativeElement.removeEventListener('wheel', this.wheelListener as EventListenerOrEventListenerObject); + } } diff --git a/src/app/cartography/events/drawings-event-source.ts b/src/app/cartography/events/drawings-event-source.ts index fa4d09f5..fb1cbabc 100644 --- a/src/app/cartography/events/drawings-event-source.ts +++ b/src/app/cartography/events/drawings-event-source.ts @@ -1,12 +1,12 @@ -import { Injectable, EventEmitter } from '@angular/core'; +import { EventEmitter, Injectable } from '@angular/core'; +import { MapDrawing } from '../models/map/map-drawing'; import { + AddedDataEvent, DraggedDataEvent, ResizedDataEvent, TextAddedDataEvent, TextEditedDataEvent, - AddedDataEvent } from './event-source'; -import { MapDrawing } from '../models/map/map-drawing'; @Injectable() export class DrawingsEventSource { diff --git a/src/app/cartography/events/event-source.ts b/src/app/cartography/events/event-source.ts index 1b7fdd72..7aa7d22b 100644 --- a/src/app/cartography/events/event-source.ts +++ b/src/app/cartography/events/event-source.ts @@ -1,8 +1,8 @@ import { TextElement } from '../models/drawings/text-element'; import { MapDrawing } from '../models/map/map-drawing'; +import { MapLabel } from '../models/map/map-label'; import { MapLink } from '../models/map/map-link'; import { MapLinkNode } from '../models/map/map-link-node'; -import { MapLabel } from '../models/map/map-label'; export class DataEventSource { constructor(public datum: T, public dx: number, public dy: number) {} diff --git a/src/app/cartography/events/links-event-source.ts b/src/app/cartography/events/links-event-source.ts index df1f2981..53341290 100644 --- a/src/app/cartography/events/links-event-source.ts +++ b/src/app/cartography/events/links-event-source.ts @@ -1,7 +1,7 @@ -import { Injectable, EventEmitter } from '@angular/core'; -import { MapLinkCreated } from './links'; +import { EventEmitter, Injectable } from '@angular/core'; import { MapLinkNode } from '../models/map/map-link-node'; import { DraggedDataEvent } from './event-source'; +import { MapLinkCreated } from './links'; @Injectable() export class LinksEventSource { diff --git a/src/app/cartography/events/moving-event-source.ts b/src/app/cartography/events/moving-event-source.ts index afa0d1a1..af55f675 100644 --- a/src/app/cartography/events/moving-event-source.ts +++ b/src/app/cartography/events/moving-event-source.ts @@ -1,6 +1,6 @@ -import { Injectable, EventEmitter } from "@angular/core"; +import { EventEmitter, Injectable } from '@angular/core'; @Injectable() export class MovingEventSource { - public movingModeState = new EventEmitter(); + public movingModeState = new EventEmitter(); } diff --git a/src/app/cartography/events/nodes-event-source.ts b/src/app/cartography/events/nodes-event-source.ts index 02406606..ea180e25 100644 --- a/src/app/cartography/events/nodes-event-source.ts +++ b/src/app/cartography/events/nodes-event-source.ts @@ -1,7 +1,7 @@ -import { Injectable, EventEmitter } from '@angular/core'; -import { DraggedDataEvent, ClickedDataEvent } from './event-source'; -import { MapNode } from '../models/map/map-node'; +import { EventEmitter, Injectable } from '@angular/core'; import { MapLabel } from '../models/map/map-label'; +import { MapNode } from '../models/map/map-node'; +import { ClickedDataEvent, DraggedDataEvent } from './event-source'; @Injectable() export class NodesEventSource { diff --git a/src/app/cartography/helpers/css-fixer.ts b/src/app/cartography/helpers/css-fixer.ts index 69e7e327..15ea0f94 100644 --- a/src/app/cartography/helpers/css-fixer.ts +++ b/src/app/cartography/helpers/css-fixer.ts @@ -1,18 +1,17 @@ -import * as csstree from 'css-tree'; - import { Injectable } from '@angular/core'; +import * as csstree from 'css-tree'; @Injectable() export class CssFixer { public fix(styles: string): string { const ast = csstree.parse(styles, { - context: 'declarationList' + context: 'declarationList', }); // fixes font-size when unit (pt|px) is not defined - ast.children.forEach(child => { + ast.children.forEach((child) => { if (child.property === 'font-size' && child.value && child.value.children) { - child.value.children.forEach(value => { + child.value.children.forEach((value) => { if (value.type === 'Number') { const fontSize = value.value.toString(); if (!(fontSize.indexOf('pt') >= 0 || fontSize.indexOf('px') >= 0)) { diff --git a/src/app/cartography/helpers/default-drawings-factory.ts b/src/app/cartography/helpers/default-drawings-factory.ts index 036679b4..7cd8044b 100644 --- a/src/app/cartography/helpers/default-drawings-factory.ts +++ b/src/app/cartography/helpers/default-drawings-factory.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; -import { TextElementFactory } from './drawings-factory/text-element-factory'; -import { EllipseElementFactory } from './drawings-factory/ellipse-element-factory'; -import { RectangleElementFactory } from './drawings-factory/rectangle-element-factory'; -import { LineElementFactory } from './drawings-factory/line-element-factory'; -import { DrawingElementFactory } from './drawings-factory/drawing-element-factory'; import { MapDrawing } from '../models/map/map-drawing'; +import { DrawingElementFactory } from './drawings-factory/drawing-element-factory'; +import { EllipseElementFactory } from './drawings-factory/ellipse-element-factory'; +import { LineElementFactory } from './drawings-factory/line-element-factory'; +import { RectangleElementFactory } from './drawings-factory/rectangle-element-factory'; +import { TextElementFactory } from './drawings-factory/text-element-factory'; @Injectable() export class DefaultDrawingsFactory { @@ -21,7 +21,7 @@ export class DefaultDrawingsFactory { text: this.textElementFactory, ellipse: this.ellipseElementFactory, rectangle: this.rectangleElementFactory, - line: this.lineElementFactory + line: this.lineElementFactory, }; } diff --git a/src/app/cartography/helpers/drawings-factory/ellipse-element-factory.ts b/src/app/cartography/helpers/drawings-factory/ellipse-element-factory.ts index b2b6b7e7..2385268b 100644 --- a/src/app/cartography/helpers/drawings-factory/ellipse-element-factory.ts +++ b/src/app/cartography/helpers/drawings-factory/ellipse-element-factory.ts @@ -1,7 +1,7 @@ -import { DrawingElementFactory } from './drawing-element-factory'; +import { Injectable } from '@angular/core'; import { DrawingElement } from '../../models/drawings/drawing-element'; import { EllipseElement } from '../../models/drawings/ellipse-element'; -import { Injectable } from '@angular/core'; +import { DrawingElementFactory } from './drawing-element-factory'; @Injectable() export class EllipseElementFactory implements DrawingElementFactory { diff --git a/src/app/cartography/helpers/drawings-factory/line-element-factory.ts b/src/app/cartography/helpers/drawings-factory/line-element-factory.ts index e5bf1fb7..f528258c 100644 --- a/src/app/cartography/helpers/drawings-factory/line-element-factory.ts +++ b/src/app/cartography/helpers/drawings-factory/line-element-factory.ts @@ -1,7 +1,7 @@ -import { DrawingElementFactory } from './drawing-element-factory'; +import { Injectable } from '@angular/core'; import { DrawingElement } from '../../models/drawings/drawing-element'; import { LineElement } from '../../models/drawings/line-element'; -import { Injectable } from '@angular/core'; +import { DrawingElementFactory } from './drawing-element-factory'; @Injectable() export class LineElementFactory implements DrawingElementFactory { diff --git a/src/app/cartography/helpers/drawings-factory/rectangle-element-factory.ts b/src/app/cartography/helpers/drawings-factory/rectangle-element-factory.ts index 96ea65fa..5e13236b 100644 --- a/src/app/cartography/helpers/drawings-factory/rectangle-element-factory.ts +++ b/src/app/cartography/helpers/drawings-factory/rectangle-element-factory.ts @@ -1,7 +1,7 @@ -import { DrawingElementFactory } from './drawing-element-factory'; +import { Injectable } from '@angular/core'; import { DrawingElement } from '../../models/drawings/drawing-element'; import { RectElement } from '../../models/drawings/rect-element'; -import { Injectable } from '@angular/core'; +import { DrawingElementFactory } from './drawing-element-factory'; @Injectable() export class RectangleElementFactory implements DrawingElementFactory { diff --git a/src/app/cartography/helpers/drawings-factory/text-element-factory.ts b/src/app/cartography/helpers/drawings-factory/text-element-factory.ts index 48449a3f..d4d978ba 100644 --- a/src/app/cartography/helpers/drawings-factory/text-element-factory.ts +++ b/src/app/cartography/helpers/drawings-factory/text-element-factory.ts @@ -1,7 +1,7 @@ -import { DrawingElementFactory } from './drawing-element-factory'; +import { Injectable } from '@angular/core'; import { DrawingElement } from '../../models/drawings/drawing-element'; import { TextElement } from '../../models/drawings/text-element'; -import { Injectable } from '@angular/core'; +import { DrawingElementFactory } from './drawing-element-factory'; @Injectable() export class TextElementFactory implements DrawingElementFactory { diff --git a/src/app/cartography/helpers/font-bbox-calculator.spec.ts b/src/app/cartography/helpers/font-bbox-calculator.spec.ts index aa608add..9425ac09 100644 --- a/src/app/cartography/helpers/font-bbox-calculator.spec.ts +++ b/src/app/cartography/helpers/font-bbox-calculator.spec.ts @@ -10,8 +10,8 @@ describe('FontBBoxCalculator', () => { it('should calculate font width and height', () => { const box = calculator.calculate('My text', 'font-family:Arial; font-size: 12px; font-weight:bold'); - expect(box.height).toEqual(14); - expect(box.width).toEqual(41.34375); + expect(box.height).toEqual(15); + expect(box.width).toEqual(41); }); xit('should calculate font width and height for different font', () => { diff --git a/src/app/cartography/helpers/font-bbox-calculator.ts b/src/app/cartography/helpers/font-bbox-calculator.ts index 69a6dee7..d06468d1 100644 --- a/src/app/cartography/helpers/font-bbox-calculator.ts +++ b/src/app/cartography/helpers/font-bbox-calculator.ts @@ -14,7 +14,7 @@ export class FontBBoxCalculator { return { width: bbox.width, - height: bbox.height + height: bbox.height, }; } } diff --git a/src/app/cartography/helpers/font-fixer.spec.ts b/src/app/cartography/helpers/font-fixer.spec.ts index 273b8756..ea9d6eaa 100644 --- a/src/app/cartography/helpers/font-fixer.spec.ts +++ b/src/app/cartography/helpers/font-fixer.spec.ts @@ -1,5 +1,5 @@ -import { FontFixer } from './font-fixer'; import { Font } from '../models/font'; +import { FontFixer } from './font-fixer'; describe('FontFixer', () => { let fixer: FontFixer; @@ -12,13 +12,13 @@ describe('FontFixer', () => { const font: Font = { font_family: 'TypeWriter', font_size: 10, - font_weight: 'bold' + font_weight: 'bold', }; expect(fixer.fix(font)).toEqual({ font_family: 'Noto Sans', font_size: 11, - font_weight: 'bold' + font_weight: 'bold', }); }); @@ -26,13 +26,13 @@ describe('FontFixer', () => { const font: Font = { font_family: 'OtherFont', font_size: 11, - font_weight: 'bold' + font_weight: 'bold', }; expect(fixer.fix(font)).toEqual({ font_family: 'OtherFont', font_size: 11, - font_weight: 'bold' + font_weight: 'bold', }); }); diff --git a/src/app/cartography/helpers/font-fixer.ts b/src/app/cartography/helpers/font-fixer.ts index 760dcdce..f038ca8a 100644 --- a/src/app/cartography/helpers/font-fixer.ts +++ b/src/app/cartography/helpers/font-fixer.ts @@ -1,5 +1,5 @@ -import * as csstree from 'css-tree'; import { Injectable } from '@angular/core'; +import * as csstree from 'css-tree'; import { Font } from '../models/font'; /** @@ -22,16 +22,16 @@ export class FontFixer { public fixStyles(styles: string) { const ast = csstree.parse(styles, { - context: 'declarationList' + context: 'declarationList', }); let fontFamilyPointer = null; let fontSizePointer = null; let isByIdentifier = true; - ast.children.forEach(child => { + ast.children.forEach((child) => { if (child.property === 'font-family' && child.value && child.value.children) { - child.value.children.forEach(value => { + child.value.children.forEach((value) => { if (value.type === 'Identifier') { fontFamilyPointer = value; } @@ -42,7 +42,7 @@ export class FontFixer { }); } if (child.property === 'font-size' && child.value && child.value.children) { - child.value.children.forEach(value => { + child.value.children.forEach((value) => { if (value.type === 'Dimension') { fontSizePointer = value; } @@ -62,7 +62,7 @@ export class FontFixer { const fixedFont = this.fix({ font_family: fontFamilyValue.split('"').join(''), - font_size: parseInt(fontSizeValue, 10) + font_size: parseInt(fontSizeValue, 10), } as Font); if (isByIdentifier) { diff --git a/src/app/cartography/helpers/in-rectangle-helper.spec.ts b/src/app/cartography/helpers/in-rectangle-helper.spec.ts index 06414819..13f92663 100644 --- a/src/app/cartography/helpers/in-rectangle-helper.spec.ts +++ b/src/app/cartography/helpers/in-rectangle-helper.spec.ts @@ -1,5 +1,5 @@ -import { InRectangleHelper } from './in-rectangle-helper'; import { Rectangle } from '../models/rectangle'; +import { InRectangleHelper } from './in-rectangle-helper'; describe('InRectangleHelper', () => { let inRectangleHelper: InRectangleHelper; diff --git a/src/app/cartography/helpers/in-rectangle-helper.ts b/src/app/cartography/helpers/in-rectangle-helper.ts index 98c86239..d72f1bb6 100644 --- a/src/app/cartography/helpers/in-rectangle-helper.ts +++ b/src/app/cartography/helpers/in-rectangle-helper.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; - import { Rectangle } from '../models/rectangle'; @Injectable() diff --git a/src/app/cartography/helpers/multi-link-calculator-helper.ts b/src/app/cartography/helpers/multi-link-calculator-helper.ts index 11c5c99e..93d96069 100644 --- a/src/app/cartography/helpers/multi-link-calculator-helper.ts +++ b/src/app/cartography/helpers/multi-link-calculator-helper.ts @@ -25,7 +25,7 @@ export class MultiLinkCalculatorHelper { } return { dx: x2_x0, - dy: y2_y0 + dy: y2_y0, }; } diff --git a/src/app/cartography/helpers/qt-dasharray-fixer.ts b/src/app/cartography/helpers/qt-dasharray-fixer.ts index 54f1ced6..31e2a7c2 100644 --- a/src/app/cartography/helpers/qt-dasharray-fixer.ts +++ b/src/app/cartography/helpers/qt-dasharray-fixer.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; -import { Font } from '../models/font'; /** * GNS3 GUI performs mapping from QT styles to SVG dasharray, but styles don't match @@ -11,7 +10,7 @@ export class QtDasharrayFixer { '25, 25': '10, 2', '5, 25': '4, 2', '5, 25, 25': '5, 5, 1, 5', - '25, 25, 5, 25, 5': '5, 2, 5, 2, 5' + '25, 25, 5, 25, 5': '5, 2, 5, 2, 5', }; public fix(dasharray: string): string { diff --git a/src/app/cartography/helpers/svg-to-drawing-converter.spec.ts b/src/app/cartography/helpers/svg-to-drawing-converter.spec.ts index 05f00655..de7734de 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter.spec.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter.spec.ts @@ -1,5 +1,5 @@ -import { SvgToDrawingConverter } from './svg-to-drawing-converter'; import { TextElement } from '../models/drawings/text-element'; +import { SvgToDrawingConverter } from './svg-to-drawing-converter'; describe('SvgToDrawingHelper', () => { let svgToDrawingConverter: SvgToDrawingConverter; diff --git a/src/app/cartography/helpers/svg-to-drawing-converter.ts b/src/app/cartography/helpers/svg-to-drawing-converter.ts index 27b70568..44a066f2 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter.ts @@ -1,11 +1,11 @@ import { Injectable } from '@angular/core'; import { DrawingElement } from '../models/drawings/drawing-element'; +import { EllipseConverter } from './svg-to-drawing-converter/ellipse-converter'; +import { ImageConverter } from './svg-to-drawing-converter/image-converter'; +import { LineConverter } from './svg-to-drawing-converter/line-converter'; +import { RectConverter } from './svg-to-drawing-converter/rect-converter'; import { SvgConverter } from './svg-to-drawing-converter/svg-converter'; import { TextConverter } from './svg-to-drawing-converter/text-converter'; -import { ImageConverter } from './svg-to-drawing-converter/image-converter'; -import { RectConverter } from './svg-to-drawing-converter/rect-converter'; -import { LineConverter } from './svg-to-drawing-converter/line-converter'; -import { EllipseConverter } from './svg-to-drawing-converter/ellipse-converter'; @Injectable() export class SvgToDrawingConverter { @@ -19,7 +19,7 @@ export class SvgToDrawingConverter { image: new ImageConverter(), rect: new RectConverter(), line: new LineConverter(), - ellipse: new EllipseConverter() + ellipse: new EllipseConverter(), }; } diff --git a/src/app/cartography/helpers/svg-to-drawing-converter/ellipse-converter.ts b/src/app/cartography/helpers/svg-to-drawing-converter/ellipse-converter.ts index b72ba356..451034eb 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter/ellipse-converter.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter/ellipse-converter.ts @@ -1,5 +1,5 @@ -import { SvgConverter } from './svg-converter'; import { EllipseElement } from '../../models/drawings/ellipse-element'; +import { SvgConverter } from './svg-converter'; export class EllipseConverter implements SvgConverter { convert(element: Element): EllipseElement { diff --git a/src/app/cartography/helpers/svg-to-drawing-converter/image-converter.ts b/src/app/cartography/helpers/svg-to-drawing-converter/image-converter.ts index e3412146..e40b28de 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter/image-converter.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter/image-converter.ts @@ -1,5 +1,5 @@ -import { SvgConverter } from './svg-converter'; import { ImageElement } from '../../models/drawings/image-element'; +import { SvgConverter } from './svg-converter'; export class ImageConverter implements SvgConverter { convert(element: Element): ImageElement { diff --git a/src/app/cartography/helpers/svg-to-drawing-converter/line-converter.ts b/src/app/cartography/helpers/svg-to-drawing-converter/line-converter.ts index 19c1a792..4fbb9857 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter/line-converter.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter/line-converter.ts @@ -1,5 +1,5 @@ -import { SvgConverter } from './svg-converter'; import { LineElement } from '../../models/drawings/line-element'; +import { SvgConverter } from './svg-converter'; export class LineConverter implements SvgConverter { convert(element: Element): LineElement { diff --git a/src/app/cartography/helpers/svg-to-drawing-converter/rect-converter.ts b/src/app/cartography/helpers/svg-to-drawing-converter/rect-converter.ts index 7682202c..a5b98d24 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter/rect-converter.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter/rect-converter.ts @@ -1,5 +1,5 @@ -import { SvgConverter } from './svg-converter'; import { RectElement } from '../../models/drawings/rect-element'; +import { SvgConverter } from './svg-converter'; export class RectConverter implements SvgConverter { convert(element: Element): RectElement { diff --git a/src/app/cartography/helpers/svg-to-drawing-converter/text-converter.ts b/src/app/cartography/helpers/svg-to-drawing-converter/text-converter.ts index 7900a2bf..387a8faa 100644 --- a/src/app/cartography/helpers/svg-to-drawing-converter/text-converter.ts +++ b/src/app/cartography/helpers/svg-to-drawing-converter/text-converter.ts @@ -1,5 +1,5 @@ -import { SvgConverter } from './svg-converter'; import { TextElement } from '../../models/drawings/text-element'; +import { SvgConverter } from './svg-converter'; export class TextConverter implements SvgConverter { convert(element: Element): TextElement { diff --git a/src/app/cartography/managers/graph-data-manager.ts b/src/app/cartography/managers/graph-data-manager.ts index 0de68ed5..278e96a0 100644 --- a/src/app/cartography/managers/graph-data-manager.ts +++ b/src/app/cartography/managers/graph-data-manager.ts @@ -1,22 +1,22 @@ import { Injectable } from '@angular/core'; -import { Node } from '../models/node'; -import { NodeToMapNodeConverter } from '../converters/map/node-to-map-node-converter'; -import { LinkToMapLinkConverter } from '../converters/map/link-to-map-link-converter'; -import { DrawingToMapDrawingConverter } from '../converters/map/drawing-to-map-drawing-converter'; -import { SymbolToMapSymbolConverter } from '../converters/map/symbol-to-map-symbol-converter'; -import { MapNode } from '../models/map/map-node'; -import { MapLink } from '../models/map/map-link'; import { Link } from '../../models/link'; -import { Drawing } from '../models/drawing'; import { Symbol } from '../../models/symbol'; -import { LayersManager } from './layers-manager'; +import { DrawingToMapDrawingConverter } from '../converters/map/drawing-to-map-drawing-converter'; +import { LinkToMapLinkConverter } from '../converters/map/link-to-map-link-converter'; +import { NodeToMapNodeConverter } from '../converters/map/node-to-map-node-converter'; +import { SymbolToMapSymbolConverter } from '../converters/map/symbol-to-map-symbol-converter'; import { - MapNodesDataSource, - MapLinksDataSource, MapDrawingsDataSource, - MapSymbolsDataSource + MapLinksDataSource, + MapNodesDataSource, + MapSymbolsDataSource, } from '../datasources/map-datasource'; import { MultiLinkCalculatorHelper } from '../helpers/multi-link-calculator-helper'; +import { Drawing } from '../models/drawing'; +import { MapLink } from '../models/map/map-link'; +import { MapNode } from '../models/map/map-node'; +import { Node } from '../models/node'; +import { LayersManager } from './layers-manager'; @Injectable() export class GraphDataManager { @@ -35,7 +35,7 @@ export class GraphDataManager { public setNodes(nodes: Node[]) { if (nodes) { - const mapNodes = nodes.map(n => this.nodeToMapNode.convert(n)); + const mapNodes = nodes.map((n) => this.nodeToMapNode.convert(n)); this.mapNodesDataSource.set(mapNodes); this.assignDataToLinks(); @@ -45,7 +45,7 @@ export class GraphDataManager { public setLinks(links: Link[]) { if (links) { - const mapLinks = links.map(l => this.linkToMapLink.convert(l)); + const mapLinks = links.map((l) => this.linkToMapLink.convert(l)); this.mapLinksDataSource.set(mapLinks); this.assignDataToLinks(); @@ -55,16 +55,16 @@ export class GraphDataManager { public setDrawings(drawings: Drawing[]) { if (drawings) { - const mapDrawings = drawings.map(d => this.drawingToMapDrawing.convert(d)); + const mapDrawings = drawings.map((d) => this.drawingToMapDrawing.convert(d)); this.mapDrawingsDataSource.set(mapDrawings); - + this.onDataUpdate(); } } public setSymbols(symbols: Symbol[]) { if (symbols) { - const mapSymbols = symbols.map(s => this.symbolToMapSymbol.convert(s)); + const mapSymbols = symbols.map((s) => this.symbolToMapSymbol.convert(s)); this.mapSymbolsDataSource.set(mapSymbols); } } diff --git a/src/app/cartography/managers/layers-manager.spec.ts b/src/app/cartography/managers/layers-manager.spec.ts index 8da09cd6..21cfb6af 100644 --- a/src/app/cartography/managers/layers-manager.spec.ts +++ b/src/app/cartography/managers/layers-manager.spec.ts @@ -1,7 +1,7 @@ -import { LayersManager } from './layers-manager'; import { MapDrawing } from '../models/map/map-drawing'; import { MapLink } from '../models/map/map-link'; import { MapNode } from '../models/map/map-node'; +import { LayersManager } from './layers-manager'; describe('LayersManager', () => { let manager: LayersManager; diff --git a/src/app/cartography/managers/layers-manager.ts b/src/app/cartography/managers/layers-manager.ts index b359489f..f0e6007b 100644 --- a/src/app/cartography/managers/layers-manager.ts +++ b/src/app/cartography/managers/layers-manager.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; - import { Layer } from '../models/layer'; -import { Dictionary } from '../models/types'; -import { MapNode } from '../models/map/map-node'; import { MapDrawing } from '../models/map/map-drawing'; import { MapLink } from '../models/map/map-link'; +import { MapNode } from '../models/map/map-node'; +import { Dictionary } from '../models/types'; @Injectable() export class LayersManager { diff --git a/src/app/cartography/managers/selection-manager.ts b/src/app/cartography/managers/selection-manager.ts index a25e18a3..e8aaf740 100644 --- a/src/app/cartography/managers/selection-manager.ts +++ b/src/app/cartography/managers/selection-manager.ts @@ -1,5 +1,4 @@ -import { Injectable, EventEmitter } from '@angular/core'; - +import { EventEmitter, Injectable } from '@angular/core'; import { Indexed } from '../datasources/map-datasource'; @Injectable() @@ -13,16 +12,16 @@ export class SelectionManager { const dictItems = this.convertToKeyDict(items); const selected = Object.keys(dictItems) - .filter(key => { + .filter((key) => { return !this.isSelectedByKey(key); }) - .map(key => dictItems[key]); + .map((key) => dictItems[key]); const unselected = Object.keys(this.selection) - .filter(key => { + .filter((key) => { return !(key in dictItems); }) - .map(key => this.selection[key]); + .map((key) => this.selection[key]); this.selection = dictItems; @@ -36,7 +35,7 @@ export class SelectionManager { } public getSelected(): Indexed[] { - return Object.keys(this.selection).map(key => this.selection[key]); + return Object.keys(this.selection).map((key) => this.selection[key]); } public isSelected(item): boolean { @@ -55,7 +54,7 @@ export class SelectionManager { private convertToKeyDict(items: Indexed[]) { const dict = {}; - items.forEach(item => { + items.forEach((item) => { dict[this.getKey(item)] = item; }); return dict; diff --git a/src/app/cartography/models/context.ts b/src/app/cartography/models/context.ts index ae90fac1..07340beb 100644 --- a/src/app/cartography/models/context.ts +++ b/src/app/cartography/models/context.ts @@ -1,6 +1,6 @@ -import { Size } from './size'; -import { Point } from './point'; import { Injectable } from '@angular/core'; +import { Point } from './point'; +import { Size } from './size'; export class Transformation { constructor(public x: number, public y: number, public k: number) {} diff --git a/src/app/cartography/models/drawings/text-element.ts b/src/app/cartography/models/drawings/text-element.ts index 79c9c7f3..ba5ea6e0 100644 --- a/src/app/cartography/models/drawings/text-element.ts +++ b/src/app/cartography/models/drawings/text-element.ts @@ -1,5 +1,5 @@ -import { DrawingElement } from './drawing-element'; import { Font } from '../font'; +import { DrawingElement } from './drawing-element'; export class TextElement implements DrawingElement, Font { height: number; diff --git a/src/app/cartography/models/layer.ts b/src/app/cartography/models/layer.ts index 88c55487..54ec697a 100644 --- a/src/app/cartography/models/layer.ts +++ b/src/app/cartography/models/layer.ts @@ -1,6 +1,6 @@ -import { MapNode } from './map/map-node'; import { MapDrawing } from './map/map-drawing'; import { MapLink } from './map/map-link'; +import { MapNode } from './map/map-node'; export class Layer { constructor( diff --git a/src/app/cartography/models/map/map-drawing.ts b/src/app/cartography/models/map/map-drawing.ts index 3510125b..f263fe34 100644 --- a/src/app/cartography/models/map/map-drawing.ts +++ b/src/app/cartography/models/map/map-drawing.ts @@ -1,5 +1,5 @@ -import { DrawingElement } from '../drawings/drawing-element'; import { Indexed } from '../../datasources/map-datasource'; +import { DrawingElement } from '../drawings/drawing-element'; export class MapDrawing implements Indexed { id: string; diff --git a/src/app/cartography/models/map/map-link-node.ts b/src/app/cartography/models/map/map-link-node.ts index 577a2d6b..b7009753 100644 --- a/src/app/cartography/models/map/map-link-node.ts +++ b/src/app/cartography/models/map/map-link-node.ts @@ -1,5 +1,5 @@ -import { MapLabel } from './map-label'; import { Indexed } from '../../datasources/map-datasource'; +import { MapLabel } from './map-label'; export class MapLinkNode implements Indexed { id: string; diff --git a/src/app/cartography/models/map/map-link.ts b/src/app/cartography/models/map/map-link.ts index 8dda2d8f..57bac994 100644 --- a/src/app/cartography/models/map/map-link.ts +++ b/src/app/cartography/models/map/map-link.ts @@ -1,7 +1,7 @@ +import { Filter } from '../../../models/filter'; +import { Indexed } from '../../datasources/map-datasource'; import { MapLinkNode } from './map-link-node'; import { MapNode } from './map-node'; -import { Indexed } from '../../datasources/map-datasource'; -import { Filter } from '../../../models/filter'; export class MapLink implements Indexed { id: string; diff --git a/src/app/cartography/models/map/map-node.ts b/src/app/cartography/models/map/map-node.ts index 9f3e9749..7c0b282e 100644 --- a/src/app/cartography/models/map/map-node.ts +++ b/src/app/cartography/models/map/map-node.ts @@ -1,6 +1,6 @@ +import { Indexed } from '../../datasources/map-datasource'; import { MapLabel } from './map-label'; import { MapPort } from './map-port'; -import { Indexed } from '../../datasources/map-datasource'; export class MapNode implements Indexed { id: string; diff --git a/src/app/cartography/models/node.ts b/src/app/cartography/models/node.ts index 28279ffa..01ffd58f 100644 --- a/src/app/cartography/models/node.ts +++ b/src/app/cartography/models/node.ts @@ -1,6 +1,5 @@ -import { Label } from './label'; import { Port } from '../../models/port'; -import { CustomAdapter } from '../../models/qemu/qemu-custom-adapter'; +import { Label } from './label'; export class PortsMapping { name: string; diff --git a/src/app/cartography/services/map-change-detector-ref.ts b/src/app/cartography/services/map-change-detector-ref.ts index 5137c342..c97c0df1 100644 --- a/src/app/cartography/services/map-change-detector-ref.ts +++ b/src/app/cartography/services/map-change-detector-ref.ts @@ -1,4 +1,4 @@ -import { Injectable, EventEmitter } from '@angular/core'; +import { EventEmitter, Injectable } from '@angular/core'; @Injectable() export class MapChangeDetectorRef { diff --git a/src/app/cartography/testing.ts b/src/app/cartography/testing.ts index a8bfefe6..8a410c9e 100644 --- a/src/app/cartography/testing.ts +++ b/src/app/cartography/testing.ts @@ -9,17 +9,12 @@ export class TestSVGCanvas { } public create() { - this.svg = select('body') - .append('svg') - .attr('width', 1000) - .attr('height', 1000); + this.svg = select('body').append('svg').attr('width', 1000).attr('height', 1000); this.canvas = this.svg.append('g').attr('class', 'canvas'); } public destroy() { - select('body') - .selectAll('svg') - .remove(); + select('body').selectAll('svg').remove(); } } diff --git a/src/app/cartography/tools/moving-tool.spec.ts b/src/app/cartography/tools/moving-tool.spec.ts index fa74340c..95001453 100644 --- a/src/app/cartography/tools/moving-tool.spec.ts +++ b/src/app/cartography/tools/moving-tool.spec.ts @@ -1,8 +1,8 @@ import { Context } from '../models/context'; -import { SVGSelection } from '../models/types'; -import { MovingTool } from './moving-tool'; -import { TestSVGCanvas } from '../testing'; import { Size } from '../models/size'; +import { SVGSelection } from '../models/types'; +import { TestSVGCanvas } from '../testing'; +import { MovingTool } from './moving-tool'; describe('MovingTool', () => { let tool: MovingTool; @@ -16,11 +16,7 @@ describe('MovingTool', () => { tool = new MovingTool(context); svg = new TestSVGCanvas(); - node = svg.canvas - .append('g') - .attr('class', 'node') - .attr('x', 10) - .attr('y', 20); + node = svg.canvas.append('g').attr('class', 'node').attr('x', 10).attr('y', 20); tool.setEnabled(true); tool.draw(svg.svg, context); @@ -39,7 +35,7 @@ describe('MovingTool', () => { relatedTarget: svg.svg.node(), screenY: 1024, screenX: 1024, - view: window + view: window, }) ); @@ -70,7 +66,7 @@ describe('MovingTool', () => { relatedTarget: svg.svg.node(), screenY: 1024, screenX: 1024, - view: window + view: window, }) ); @@ -101,7 +97,7 @@ describe('MovingTool', () => { relatedTarget: svg.svg.node(), screenY: 1024, screenX: 1024, - view: window + view: window, }) ); diff --git a/src/app/cartography/tools/moving-tool.ts b/src/app/cartography/tools/moving-tool.ts index 6590fe85..887a734e 100644 --- a/src/app/cartography/tools/moving-tool.ts +++ b/src/app/cartography/tools/moving-tool.ts @@ -1,10 +1,8 @@ import { Injectable } from '@angular/core'; - -import { D3ZoomEvent, zoom, ZoomBehavior } from 'd3-zoom'; import { event } from 'd3-selection'; - -import { SVGSelection } from '../models/types'; +import { D3ZoomEvent, zoom, ZoomBehavior } from 'd3-zoom'; import { Context } from '../models/context'; +import { SVGSelection } from '../models/types'; @Injectable() export class MovingTool { @@ -42,7 +40,7 @@ export class MovingTool { private activate(selection: SVGSelection) { const self = this; - const onZoom = function(this: SVGSVGElement) { + const onZoom = function (this: SVGSVGElement) { const canvas = selection.select('g.canvas'); const e: D3ZoomEvent = event; canvas.attr('transform', () => { diff --git a/src/app/cartography/tools/selection-tool.spec.ts b/src/app/cartography/tools/selection-tool.spec.ts index bda014e5..73ebe9fb 100644 --- a/src/app/cartography/tools/selection-tool.spec.ts +++ b/src/app/cartography/tools/selection-tool.spec.ts @@ -1,9 +1,9 @@ -import { SelectionTool } from './selection-tool'; -import { Context } from '../models/context'; -import { SVGSelection } from '../models/types'; -import { Rectangle } from '../models/rectangle'; -import { TestSVGCanvas } from '../testing'; import { SelectionEventSource } from '../events/selection-event-source'; +import { Context } from '../models/context'; +import { Rectangle } from '../models/rectangle'; +import { SVGSelection } from '../models/types'; +import { TestSVGCanvas } from '../testing'; +import { SelectionTool } from './selection-tool'; describe('SelectionTool', () => { let tool: SelectionTool; diff --git a/src/app/cartography/tools/selection-tool.ts b/src/app/cartography/tools/selection-tool.ts index 40c037a9..50be5b42 100644 --- a/src/app/cartography/tools/selection-tool.ts +++ b/src/app/cartography/tools/selection-tool.ts @@ -1,11 +1,10 @@ -import { Injectable, EventEmitter } from '@angular/core'; -import { mouse, select, event } from 'd3-selection'; +import { EventEmitter, Injectable } from '@angular/core'; +import { event, mouse, select } from 'd3-selection'; import { Subject } from 'rxjs'; - -import { SVGSelection } from '../models/types'; +import { SelectionEventSource } from '../events/selection-event-source'; import { Context } from '../models/context'; import { Rectangle } from '../models/rectangle'; -import { SelectionEventSource } from '../events/selection-event-source'; +import { SVGSelection } from '../models/types'; @Injectable() export class SelectionTool { @@ -17,14 +16,9 @@ export class SelectionTool { private path; private enabled = false; - public constructor( - private context: Context, - private selectionEventSource: SelectionEventSource - ) {} + public constructor(private context: Context, private selectionEventSource: SelectionEventSource) {} - public disableContextMenu(){ - - } + public disableContextMenu() {} public setEnabled(enabled) { this.enabled = enabled; @@ -34,7 +28,7 @@ export class SelectionTool { private activate(selection) { const self = this; - selection.on('mousedown', function() { + selection.on('mousedown', function () { // prevent deselection on right click if (event.button == 2) { selection.on('contextmenu', () => { @@ -55,11 +49,11 @@ export class SelectionTool { selection.selectAll(SelectionTool.SELECTABLE_CLASS).classed('selected', false); subject - .on('mousemove.selection', function() { + .on('mousemove.selection', function () { const end = self.transformation(mouse(parent)); self.moveSelection(start, end); }) - .on('mouseup.selection', function() { + .on('mouseup.selection', function () { const end = self.transformation(mouse(parent)); self.endSelection(start, end); subject.on('mousemove.selection', null).on('mouseup.selection', null); @@ -100,9 +94,12 @@ export class SelectionTool { } private moveSelection(start, move) { - let x = start[0]/this.context.transformation.k; - let y = start[1]/this.context.transformation.k; - this.path.attr('d', this.rect(x, y, move[0]/this.context.transformation.k - x, move[1]/this.context.transformation.k - y)); + let x = start[0] / this.context.transformation.k; + let y = start[1] / this.context.transformation.k; + this.path.attr( + 'd', + this.rect(x, y, move[0] / this.context.transformation.k - x, move[1] / this.context.transformation.k - y) + ); this.selectedEvent(start, move); } @@ -127,7 +124,7 @@ export class SelectionTool { const transformation_point = this.context.getZeroZeroTransformationPoint(); return [ point[0] - transformation_point.x - this.context.transformation.x, - point[1] - transformation_point.y - this.context.transformation.y + point[1] - transformation_point.y - this.context.transformation.y, ]; } } diff --git a/src/app/cartography/widgets/drawing-line.ts b/src/app/cartography/widgets/drawing-line.ts index 5f7f85bd..0fa27da8 100644 --- a/src/app/cartography/widgets/drawing-line.ts +++ b/src/app/cartography/widgets/drawing-line.ts @@ -1,12 +1,10 @@ import { Injectable } from '@angular/core'; - -import { line } from 'd3-shape'; import { mouse } from 'd3-selection'; - -import { DrawingLine } from '../models/drawing-line'; -import { SVGSelection } from '../models/types'; -import { Point } from '../models/point'; +import { line } from 'd3-shape'; import { Context } from '../models/context'; +import { DrawingLine } from '../models/drawing-line'; +import { Point } from '../models/point'; +import { SVGSelection } from '../models/types'; @Injectable() export class DrawingLineWidget { @@ -23,7 +21,7 @@ export class DrawingLineWidget { this.drawingLine.start = new Point(x, y); this.drawingLine.end = new Point(x, y); - const over = function(this, d, i) { + const over = function (this, d, i) { const node = self.selection.select('g.canvas').node(); const coordinates = mouse(node); self.drawingLine.end.x = coordinates[0]; @@ -60,7 +58,10 @@ export class DrawingLineWidget { if (this.drawing) { link_data = [ - [[this.drawingLine.start.x, this.drawingLine.start.y], [this.drawingLine.end.x, this.drawingLine.end.y]] + [ + [this.drawingLine.start.x, this.drawingLine.start.y], + [this.drawingLine.end.x, this.drawingLine.end.y], + ], ]; } @@ -72,11 +73,7 @@ export class DrawingLineWidget { const enter = tool.enter().append('path'); - tool - .merge(enter) - .attr('d', value_line) - .attr('stroke', '#000') - .attr('stroke-width', '2'); + tool.merge(enter).attr('d', value_line).attr('stroke', '#000').attr('stroke-width', '2'); tool.exit().remove(); } diff --git a/src/app/cartography/widgets/drawing.ts b/src/app/cartography/widgets/drawing.ts index 2f55b8dc..167cc472 100644 --- a/src/app/cartography/widgets/drawing.ts +++ b/src/app/cartography/widgets/drawing.ts @@ -1,19 +1,18 @@ import { Injectable } from '@angular/core'; - -import { Widget } from './widget'; +import { MapSettingsService } from '../../services/mapsettings.service'; +import { SelectionManager } from '../managers/selection-manager'; +import { EllipseElement } from '../models/drawings/ellipse-element'; +import { LineElement } from '../models/drawings/line-element'; +import { RectElement } from '../models/drawings/rect-element'; +import { MapDrawing } from '../models/map/map-drawing'; import { SVGSelection } from '../models/types'; import { DrawingShapeWidget } from './drawings/drawing-shape-widget'; -import { TextDrawingWidget } from './drawings/text-drawing'; -import { ImageDrawingWidget } from './drawings/image-drawing'; -import { RectDrawingWidget } from './drawings/rect-drawing'; -import { LineDrawingWidget } from './drawings/line-drawing'; import { EllipseDrawingWidget } from './drawings/ellipse-drawing'; -import { MapDrawing } from '../models/map/map-drawing'; -import { SelectionManager } from '../managers/selection-manager'; -import { LineElement } from '../models/drawings/line-element'; -import { EllipseElement } from '../models/drawings/ellipse-element'; -import { RectElement } from '../models/drawings/rect-element'; -import { MapSettingsService } from '../../services/mapsettings.service'; +import { ImageDrawingWidget } from './drawings/image-drawing'; +import { LineDrawingWidget } from './drawings/line-drawing'; +import { RectDrawingWidget } from './drawings/rect-drawing'; +import { TextDrawingWidget } from './drawings/text-drawing'; +import { Widget } from './widget'; @Injectable() export class DrawingWidget implements Widget { @@ -33,52 +32,49 @@ export class DrawingWidget implements Widget { this.imageDrawingWidget, this.rectDrawingWidget, this.lineDrawingWidget, - this.ellipseDrawingWidget + this.ellipseDrawingWidget, ]; } public draw(view: SVGSelection) { const drawing_body = view.selectAll('g.drawing_body').data((l: MapDrawing) => [l]); - const drawing_body_enter = drawing_body - .enter() - .append('g') - .attr('class', 'drawing_body'); + const drawing_body_enter = drawing_body.enter().append('g').attr('class', 'drawing_body'); const drawing_body_merge = drawing_body.merge(drawing_body_enter).attr('transform', (d: MapDrawing) => { return `translate(${d.x},${d.y}) rotate(${d.rotation})`; }); - this.drawingWidgets.forEach(widget => { + this.drawingWidgets.forEach((widget) => { widget.draw(drawing_body_merge); }); drawing_body_merge.select('.layer_label_wrapper').remove(); if (this.mapSettingsService.isLayerNumberVisible) { drawing_body_merge - .filter(n => ((n.element instanceof RectElement) || (n.element instanceof EllipseElement))) + .filter((n) => n.element instanceof RectElement || n.element instanceof EllipseElement) .append('rect') .attr('class', 'layer_label_wrapper') .attr('width', '26') .attr('height', '26') - .attr('x', n => n.element ? n.element.width/2 - 13 : 0) - .attr('y', n => n.element ? n.element.height/2 - 13 : 0) + .attr('x', (n) => (n.element ? n.element.width / 2 - 13 : 0)) + .attr('y', (n) => (n.element ? n.element.height / 2 - 13 : 0)) .attr('fill', 'red'); } drawing_body_merge.select('.layer_label').remove(); if (this.mapSettingsService.isLayerNumberVisible) { drawing_body_merge - .filter(n => ((n.element instanceof RectElement) || (n.element instanceof EllipseElement))) + .filter((n) => n.element instanceof RectElement || n.element instanceof EllipseElement) .append('text') .attr('class', 'layer_label') .text((elem) => elem.z) - .attr('x', function(n) { - if(n.z >= 100 ) return n.element ? n.element.width/2 - 13 : 0 - else if(n.z >= 10 ) return n.element ? n.element.width/2 - 9 : 0 - else return n.element.width/2 - 5 + .attr('x', function (n) { + if (n.z >= 100) return n.element ? n.element.width / 2 - 13 : 0; + else if (n.z >= 10) return n.element ? n.element.width / 2 - 9 : 0; + else return n.element.width / 2 - 5; }) - .attr('y', n => n.element ? n.element.height/2 + 5 : 0) + .attr('y', (n) => (n.element ? n.element.height / 2 + 5 : 0)) .attr('style', () => { const styles: string[] = []; styles.push(`font-family: "Noto Sans"`); @@ -93,10 +89,10 @@ export class DrawingWidget implements Widget { .select('line.top') .attr('stroke', 'transparent') .attr('stroke-width', '8px') - .attr('x1', drawing => + .attr('x1', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cx - drawing.element.width / 10 : '0' ) - .attr('x2', drawing => + .attr('x2', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cx + drawing.element.width / 10 : drawing.element.width @@ -110,16 +106,16 @@ export class DrawingWidget implements Widget { .select('line.bottom') .attr('stroke', 'transparent') .attr('stroke-width', '8px') - .attr('x1', drawing => + .attr('x1', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cx - drawing.element.width / 10 : '0' ) - .attr('x2', drawing => + .attr('x2', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cx + drawing.element.width / 10 : drawing.element.width ) - .attr('y1', drawing => drawing.element.height) - .attr('y2', drawing => drawing.element.height) + .attr('y1', (drawing) => drawing.element.height) + .attr('y2', (drawing) => drawing.element.height) .attr('draggable', 'true') .attr('cursor', 'ns-resize'); @@ -129,10 +125,10 @@ export class DrawingWidget implements Widget { .attr('stroke-width', '8px') .attr('x1', '0') .attr('x2', '0') - .attr('y1', drawing => + .attr('y1', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cy - drawing.element.height / 10 : '0' ) - .attr('y2', drawing => + .attr('y2', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cy + drawing.element.height / 10 : drawing.element.height @@ -144,12 +140,12 @@ export class DrawingWidget implements Widget { .select('line.left') .attr('stroke', 'transparent') .attr('stroke-width', '8px') - .attr('x1', drawing => drawing.element.width) - .attr('x2', drawing => drawing.element.width) - .attr('y1', drawing => + .attr('x1', (drawing) => drawing.element.width) + .attr('x2', (drawing) => drawing.element.width) + .attr('y1', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cy - drawing.element.height / 10 : '0' ) - .attr('y2', drawing => + .attr('y2', (drawing) => drawing.element instanceof EllipseElement ? drawing.element.cy + drawing.element.height / 10 : drawing.element.height @@ -162,8 +158,8 @@ export class DrawingWidget implements Widget { .attr('draggable', 'true') .attr('fill', 'transparent') .attr('stroke', 'transparent') - .attr('cx', drawing => (drawing.element as LineElement).x1) - .attr('cy', drawing => (drawing.element as LineElement).y1) + .attr('cx', (drawing) => (drawing.element as LineElement).x1) + .attr('cy', (drawing) => (drawing.element as LineElement).y1) .attr('r', 10) .attr('cursor', 'move'); @@ -172,8 +168,8 @@ export class DrawingWidget implements Widget { .attr('draggable', 'true') .attr('fill', 'transparent') .attr('stroke', 'transparent') - .attr('cx', drawing => (drawing.element as LineElement).x2) - .attr('cy', drawing => (drawing.element as LineElement).y2) + .attr('cx', (drawing) => (drawing.element as LineElement).x2) + .attr('cy', (drawing) => (drawing.element as LineElement).y2) .attr('r', 10) .attr('cursor', 'move'); diff --git a/src/app/cartography/widgets/drawings.backup.ts b/src/app/cartography/widgets/drawings.backup.ts index 5ecb032b..239768ac 100644 --- a/src/app/cartography/widgets/drawings.backup.ts +++ b/src/app/cartography/widgets/drawings.backup.ts @@ -1,19 +1,18 @@ -import { Injectable, EventEmitter } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { Layer } from '../models/layer'; -import { SvgToDrawingConverter } from '../helpers/svg-to-drawing-converter'; -import { Draggable, DraggableDrag, DraggableStart, DraggableEnd } from '../events/draggable'; -import { DrawingWidget } from './drawing'; -import { drag, D3DragEvent } from 'd3-drag'; +import { EventEmitter, Injectable } from '@angular/core'; +import { drag } from 'd3-drag'; import { event } from 'd3-selection'; -import { MapDrawing } from '../models/map/map-drawing'; +import { Draggable } from '../events/draggable'; +import { ResizingEnd } from '../events/resizing'; +import { SvgToDrawingConverter } from '../helpers/svg-to-drawing-converter'; +import { MapSettingsManager } from '../managers/map-settings-manager'; import { Context } from '../models/context'; import { EllipseElement } from '../models/drawings/ellipse-element'; -import { ResizingEnd } from '../events/resizing'; import { LineElement } from '../models/drawings/line-element'; -import { MapSettingsManager } from '../managers/map-settings-manager'; +import { Layer } from '../models/layer'; +import { MapDrawing } from '../models/map/map-drawing'; +import { SVGSelection } from '../models/types'; +import { DrawingWidget } from './drawing'; +import { Widget } from './widget'; @Injectable() export class DrawingsWidget implements Widget { diff --git a/src/app/cartography/widgets/drawings.ts b/src/app/cartography/widgets/drawings.ts index 734c0bfd..a4f9a174 100644 --- a/src/app/cartography/widgets/drawings.ts +++ b/src/app/cartography/widgets/drawings.ts @@ -1,20 +1,19 @@ -import { Injectable, EventEmitter } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { Layer } from '../models/layer'; -import { SvgToDrawingConverter } from '../helpers/svg-to-drawing-converter'; -import { Draggable, DraggableDrag, DraggableStart, DraggableEnd } from '../events/draggable'; -import { DrawingWidget } from './drawing'; -import { drag, D3DragEvent } from 'd3-drag'; +import { EventEmitter, Injectable } from '@angular/core'; +import { drag } from 'd3-drag'; import { event } from 'd3-selection'; -import { MapDrawing } from '../models/map/map-drawing'; +import { Draggable } from '../events/draggable'; +import { DrawingContextMenu } from '../events/event-source'; +import { ResizingEnd } from '../events/resizing'; +import { SvgToDrawingConverter } from '../helpers/svg-to-drawing-converter'; +import { MapSettingsManager } from '../managers/map-settings-manager'; import { Context } from '../models/context'; import { EllipseElement } from '../models/drawings/ellipse-element'; -import { ResizingEnd } from '../events/resizing'; import { LineElement } from '../models/drawings/line-element'; -import { MapSettingsManager } from '../managers/map-settings-manager'; -import { DrawingContextMenu } from '../events/event-source'; +import { Layer } from '../models/layer'; +import { MapDrawing } from '../models/map/map-drawing'; +import { SVGSelection } from '../models/types'; +import { DrawingWidget } from './drawing'; +import { Widget } from './widget'; @Injectable() export class DrawingsWidget implements Widget { @@ -111,15 +110,18 @@ export class DrawingsWidget implements Widget { } } } else { - dy = y - (evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)); - y = evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); + dy = + y - + (evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)); + y = evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); if (datum.element.height + dy < 0) { isReflectedVertical = false; y = topEdge; datum.element.height = Math.abs(datum.element.height + evt.dy); } else { - datum.y = evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); + datum.y = + evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); datum.element.height += dy; if (datum.element instanceof EllipseElement) { (datum.element as EllipseElement).cy = @@ -143,7 +145,7 @@ export class DrawingsWidget implements Widget { let top = drag() .on('start', (datum: MapDrawing) => { - y = event.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); + y = event.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); bottomEdge = y + datum.element.height; document.body.style.cursor = 'ns-resize'; }) @@ -151,15 +153,18 @@ export class DrawingsWidget implements Widget { const evt = event; if (!isReflectedVertical) { - dy = y - (evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)); - y = evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); + dy = + y - + (evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)); + y = evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); if (datum.element.height + dy < 0) { y = bottomEdge; isReflectedVertical = true; datum.element.height = Math.abs(datum.element.height + evt.dy); } else { - datum.y = evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); + datum.y = + evt.sourceEvent.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y); datum.element.height += dy; if (datum.element instanceof EllipseElement) { (datum.element as EllipseElement).cy = @@ -207,7 +212,7 @@ export class DrawingsWidget implements Widget { let isReflectedHorizontal: boolean = false; let right = drag() .on('start', (datum: MapDrawing) => { - x = event.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); + x = event.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); leftEdge = x + datum.element.width; document.body.style.cursor = 'ew-resize'; }) @@ -215,15 +220,18 @@ export class DrawingsWidget implements Widget { const evt = event; if (!isReflectedHorizontal) { - dx = x - (evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)); - x = evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); + dx = + x - + (evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)); + x = evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); if (datum.element.width + dx < 0) { x = leftEdge; isReflectedHorizontal = true; datum.element.width = Math.abs(datum.element.width + evt.dx); } else { - datum.x = evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); + datum.x = + evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); datum.element.width += dx; if (datum.element instanceof EllipseElement) { (datum.element as EllipseElement).cx = @@ -290,15 +298,18 @@ export class DrawingsWidget implements Widget { datum.element.width = datum.element.width + evt.dx < 0 ? 1 : (datum.element.width += evt.dx); } } else { - dx = x - (evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)); - x = evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); + dx = + x - + (evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)); + x = evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); if (datum.element.width + dx < 0) { x = rightEdge; isReflectedHorizontal = false; datum.element.width = Math.abs(datum.element.width + evt.dx); } else { - datum.x = evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); + datum.x = + evt.sourceEvent.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x); datum.element.width += dx; if (datum.element instanceof EllipseElement) { (datum.element as EllipseElement).cx = diff --git a/src/app/cartography/widgets/drawings/ellipse-drawing.spec.ts b/src/app/cartography/widgets/drawings/ellipse-drawing.spec.ts index 82a2918f..20279666 100644 --- a/src/app/cartography/widgets/drawings/ellipse-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/ellipse-drawing.spec.ts @@ -1,7 +1,7 @@ -import { TestSVGCanvas } from '../../testing'; -import { EllipseElement } from '../../models/drawings/ellipse-element'; import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; +import { EllipseElement } from '../../models/drawings/ellipse-element'; import { MapDrawing } from '../../models/map/map-drawing'; +import { TestSVGCanvas } from '../../testing'; import { EllipseDrawingWidget } from './ellipse-drawing'; describe('EllipseDrawingWidget', () => { @@ -33,10 +33,7 @@ describe('EllipseDrawingWidget', () => { drawing.element = ellipse; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); diff --git a/src/app/cartography/widgets/drawings/ellipse-drawing.ts b/src/app/cartography/widgets/drawings/ellipse-drawing.ts index 8fce84d2..06435a9f 100644 --- a/src/app/cartography/widgets/drawings/ellipse-drawing.ts +++ b/src/app/cartography/widgets/drawings/ellipse-drawing.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; - -import { SVGSelection } from '../../models/types'; -import { EllipseElement } from '../../models/drawings/ellipse-element'; -import { DrawingShapeWidget } from './drawing-shape-widget'; import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; +import { EllipseElement } from '../../models/drawings/ellipse-element'; import { MapDrawing } from '../../models/map/map-drawing'; +import { SVGSelection } from '../../models/types'; +import { DrawingShapeWidget } from './drawing-shape-widget'; @Injectable() export class EllipseDrawingWidget implements DrawingShapeWidget { @@ -17,25 +16,13 @@ export class EllipseDrawingWidget implements DrawingShapeWidget { return d.element && d.element instanceof EllipseElement ? [d.element] : []; }); - drawing - .enter() - .append('line') - .attr('class', 'top'); + drawing.enter().append('line').attr('class', 'top'); - drawing - .enter() - .append('line') - .attr('class', 'bottom'); + drawing.enter().append('line').attr('class', 'bottom'); - drawing - .enter() - .append('line') - .attr('class', 'right'); + drawing.enter().append('line').attr('class', 'right'); - drawing - .enter() - .append('line') - .attr('class', 'left'); + drawing.enter().append('line').attr('class', 'left'); const drawing_enter = drawing .enter() @@ -45,15 +32,15 @@ export class EllipseDrawingWidget implements DrawingShapeWidget { const merge = drawing.merge(drawing_enter); merge - .attr('fill', ellipse => ellipse.fill) - .attr('fill-opacity', ellipse => ellipse.fill_opacity) - .attr('stroke', ellipse => ellipse.stroke) - .attr('stroke-width', ellipse => ellipse.stroke_width) - .attr('stroke-dasharray', ellipse => this.qtDasharrayFixer.fix(ellipse.stroke_dasharray)) - .attr('cx', ellipse => ellipse.cx) - .attr('cy', ellipse => ellipse.cy) - .attr('rx', ellipse => ellipse.rx) - .attr('ry', ellipse => ellipse.ry); + .attr('fill', (ellipse) => ellipse.fill) + .attr('fill-opacity', (ellipse) => ellipse.fill_opacity) + .attr('stroke', (ellipse) => ellipse.stroke) + .attr('stroke-width', (ellipse) => ellipse.stroke_width) + .attr('stroke-dasharray', (ellipse) => this.qtDasharrayFixer.fix(ellipse.stroke_dasharray)) + .attr('cx', (ellipse) => ellipse.cx) + .attr('cy', (ellipse) => ellipse.cy) + .attr('rx', (ellipse) => ellipse.rx) + .attr('ry', (ellipse) => ellipse.ry); drawing.exit().remove(); } diff --git a/src/app/cartography/widgets/drawings/image-drawing.spec.ts b/src/app/cartography/widgets/drawings/image-drawing.spec.ts index 119d0d25..f9eceb84 100644 --- a/src/app/cartography/widgets/drawings/image-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/image-drawing.spec.ts @@ -1,7 +1,7 @@ -import { TestSVGCanvas } from '../../testing'; -import { ImageDrawingWidget } from './image-drawing'; import { ImageElement } from '../../models/drawings/image-element'; import { MapDrawing } from '../../models/map/map-drawing'; +import { TestSVGCanvas } from '../../testing'; +import { ImageDrawingWidget } from './image-drawing'; describe('ImageDrawingWidget', () => { let svg: TestSVGCanvas; @@ -26,10 +26,7 @@ describe('ImageDrawingWidget', () => { drawing.element = image; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); diff --git a/src/app/cartography/widgets/drawings/image-drawing.ts b/src/app/cartography/widgets/drawings/image-drawing.ts index 0cf94b72..430b5d30 100644 --- a/src/app/cartography/widgets/drawings/image-drawing.ts +++ b/src/app/cartography/widgets/drawings/image-drawing.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; - -import { SVGSelection } from '../../models/types'; import { ImageElement } from '../../models/drawings/image-element'; -import { DrawingShapeWidget } from './drawing-shape-widget'; import { MapDrawing } from '../../models/map/map-drawing'; +import { SVGSelection } from '../../models/types'; +import { DrawingShapeWidget } from './drawing-shape-widget'; @Injectable() export class ImageDrawingWidget implements DrawingShapeWidget { @@ -12,17 +11,14 @@ export class ImageDrawingWidget implements DrawingShapeWidget { return d.element && d.element instanceof ImageElement ? [d.element] : []; }); - const drawing_enter = drawing - .enter() - .append('image') - .attr('class', 'image_element noselect'); + const drawing_enter = drawing.enter().append('image').attr('class', 'image_element noselect'); const merge = drawing.merge(drawing_enter); merge .attr('xlink:href', (image: ImageElement) => image.data) - .attr('width', image => image.width) - .attr('height', image => image.height); + .attr('width', (image) => image.width) + .attr('height', (image) => image.height); drawing.exit().remove(); } diff --git a/src/app/cartography/widgets/drawings/line-drawing.spec.ts b/src/app/cartography/widgets/drawings/line-drawing.spec.ts index 32f673a6..aaa6ca73 100644 --- a/src/app/cartography/widgets/drawings/line-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/line-drawing.spec.ts @@ -1,8 +1,8 @@ +import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; +import { LineElement } from '../../models/drawings/line-element'; +import { MapDrawing } from '../../models/map/map-drawing'; import { TestSVGCanvas } from '../../testing'; import { LineDrawingWidget } from './line-drawing'; -import { LineElement } from '../../models/drawings/line-element'; -import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; -import { MapDrawing } from '../../models/map/map-drawing'; describe('LineDrawingWidget', () => { let svg: TestSVGCanvas; @@ -31,10 +31,7 @@ describe('LineDrawingWidget', () => { drawing.element = line; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); diff --git a/src/app/cartography/widgets/drawings/line-drawing.ts b/src/app/cartography/widgets/drawings/line-drawing.ts index c642d9c8..6027ddce 100644 --- a/src/app/cartography/widgets/drawings/line-drawing.ts +++ b/src/app/cartography/widgets/drawings/line-drawing.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; - -import { SVGSelection } from '../../models/types'; -import { LineElement } from '../../models/drawings/line-element'; -import { DrawingShapeWidget } from './drawing-shape-widget'; import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; +import { LineElement } from '../../models/drawings/line-element'; import { MapDrawing } from '../../models/map/map-drawing'; +import { SVGSelection } from '../../models/types'; +import { DrawingShapeWidget } from './drawing-shape-widget'; @Injectable() export class LineDrawingWidget implements DrawingShapeWidget { @@ -15,31 +14,22 @@ export class LineDrawingWidget implements DrawingShapeWidget { return d.element && d.element instanceof LineElement ? [d.element] : []; }); - drawing - .enter() - .append('circle') - .attr('class', 'right'); + drawing.enter().append('circle').attr('class', 'right'); - drawing - .enter() - .append('circle') - .attr('class', 'left'); + drawing.enter().append('circle').attr('class', 'left'); - const drawing_enter = drawing - .enter() - .append('line') - .attr('class', 'line_element noselect'); + const drawing_enter = drawing.enter().append('line').attr('class', 'line_element noselect'); const merge = drawing.merge(drawing_enter); merge - .attr('stroke', line => line.stroke) - .attr('stroke-width', line => line.stroke_width) - .attr('stroke-dasharray', line => this.qtDasharrayFixer.fix(line.stroke_dasharray)) - .attr('x1', line => line.x1) - .attr('x2', line => line.x2) - .attr('y1', line => line.y1) - .attr('y2', line => line.y2); + .attr('stroke', (line) => line.stroke) + .attr('stroke-width', (line) => line.stroke_width) + .attr('stroke-dasharray', (line) => this.qtDasharrayFixer.fix(line.stroke_dasharray)) + .attr('x1', (line) => line.x1) + .attr('x2', (line) => line.x2) + .attr('y1', (line) => line.y1) + .attr('y2', (line) => line.y2); drawing.exit().remove(); } diff --git a/src/app/cartography/widgets/drawings/rect-drawing.spec.ts b/src/app/cartography/widgets/drawings/rect-drawing.spec.ts index 2e14ad1b..ecd5e63a 100644 --- a/src/app/cartography/widgets/drawings/rect-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/rect-drawing.spec.ts @@ -1,8 +1,8 @@ +import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; +import { RectElement } from '../../models/drawings/rect-element'; +import { MapDrawing } from '../../models/map/map-drawing'; import { TestSVGCanvas } from '../../testing'; import { RectDrawingWidget } from './rect-drawing'; -import { RectElement } from '../../models/drawings/rect-element'; -import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; -import { MapDrawing } from '../../models/map/map-drawing'; describe('RectDrawingWidget', () => { let svg: TestSVGCanvas; @@ -31,10 +31,7 @@ describe('RectDrawingWidget', () => { drawing.element = rect; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); diff --git a/src/app/cartography/widgets/drawings/rect-drawing.ts b/src/app/cartography/widgets/drawings/rect-drawing.ts index 1661d1c1..de6a31d2 100644 --- a/src/app/cartography/widgets/drawings/rect-drawing.ts +++ b/src/app/cartography/widgets/drawings/rect-drawing.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; - -import { SVGSelection } from '../../models/types'; -import { RectElement } from '../../models/drawings/rect-element'; -import { DrawingShapeWidget } from './drawing-shape-widget'; import { QtDasharrayFixer } from '../../helpers/qt-dasharray-fixer'; +import { RectElement } from '../../models/drawings/rect-element'; import { MapDrawing } from '../../models/map/map-drawing'; +import { SVGSelection } from '../../models/types'; +import { DrawingShapeWidget } from './drawing-shape-widget'; @Injectable() export class RectDrawingWidget implements DrawingShapeWidget { @@ -15,41 +14,26 @@ export class RectDrawingWidget implements DrawingShapeWidget { return d.element && d.element instanceof RectElement ? [d.element] : []; }); - drawing - .enter() - .append('line') - .attr('class', 'top'); + drawing.enter().append('line').attr('class', 'top'); - drawing - .enter() - .append('line') - .attr('class', 'bottom'); + drawing.enter().append('line').attr('class', 'bottom'); - drawing - .enter() - .append('line') - .attr('class', 'right'); + drawing.enter().append('line').attr('class', 'right'); - drawing - .enter() - .append('line') - .attr('class', 'left'); + drawing.enter().append('line').attr('class', 'left'); - const drawing_enter = drawing - .enter() - .append('rect') - .attr('class', 'rect_element noselect'); + const drawing_enter = drawing.enter().append('rect').attr('class', 'rect_element noselect'); const merge = drawing.merge(drawing_enter); merge - .attr('fill', rect => rect.fill) - .attr('fill-opacity', rect => rect.fill_opacity) - .attr('stroke', rect => rect.stroke) - .attr('stroke-width', rect => rect.stroke_width) - .attr('stroke-dasharray', rect => this.qtDasharrayFixer.fix(rect.stroke_dasharray)) - .attr('width', rect => rect.width) - .attr('height', rect => rect.height); + .attr('fill', (rect) => rect.fill) + .attr('fill-opacity', (rect) => rect.fill_opacity) + .attr('stroke', (rect) => rect.stroke) + .attr('stroke-width', (rect) => rect.stroke_width) + .attr('stroke-dasharray', (rect) => this.qtDasharrayFixer.fix(rect.stroke_dasharray)) + .attr('width', (rect) => rect.width) + .attr('height', (rect) => rect.height); drawing.exit().remove(); } diff --git a/src/app/cartography/widgets/drawings/text-drawing.spec.ts b/src/app/cartography/widgets/drawings/text-drawing.spec.ts index 3425b36d..f4b42733 100644 --- a/src/app/cartography/widgets/drawings/text-drawing.spec.ts +++ b/src/app/cartography/widgets/drawings/text-drawing.spec.ts @@ -1,8 +1,8 @@ +import { FontFixer } from '../../helpers/font-fixer'; +import { TextElement } from '../../models/drawings/text-element'; +import { MapDrawing } from '../../models/map/map-drawing'; import { TestSVGCanvas } from '../../testing'; import { TextDrawingWidget } from './text-drawing'; -import { TextElement } from '../../models/drawings/text-element'; -import { FontFixer } from '../../helpers/font-fixer'; -import { MapDrawing } from '../../models/map/map-drawing'; describe('TextDrawingWidget', () => { let svg: TestSVGCanvas; @@ -32,10 +32,7 @@ describe('TextDrawingWidget', () => { drawing.element = text; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); @@ -55,10 +52,7 @@ describe('TextDrawingWidget', () => { drawing.element = text; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); @@ -81,10 +75,7 @@ describe('TextDrawingWidget', () => { drawing.element = text; const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); - const drawings_enter = drawings - .enter() - .append('g') - .classed('drawing', true); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); const drawings_merge = drawings.merge(drawings_enter); widget.draw(drawings_merge); diff --git a/src/app/cartography/widgets/drawings/text-drawing.ts b/src/app/cartography/widgets/drawings/text-drawing.ts index 09bac88c..78876d75 100644 --- a/src/app/cartography/widgets/drawings/text-drawing.ts +++ b/src/app/cartography/widgets/drawings/text-drawing.ts @@ -1,11 +1,10 @@ import { Injectable } from '@angular/core'; - -import { SVGSelection } from '../../models/types'; -import { TextElement } from '../../models/drawings/text-element'; -import { DrawingShapeWidget } from './drawing-shape-widget'; -import { FontFixer } from '../../helpers/font-fixer'; import { select } from 'd3-selection'; +import { FontFixer } from '../../helpers/font-fixer'; +import { TextElement } from '../../models/drawings/text-element'; import { MapDrawing } from '../../models/map/map-drawing'; +import { SVGSelection } from '../../models/types'; +import { DrawingShapeWidget } from './drawing-shape-widget'; @Injectable() export class TextDrawingWidget implements DrawingShapeWidget { @@ -18,10 +17,7 @@ export class TextDrawingWidget implements DrawingShapeWidget { return d.element && d.element instanceof TextElement ? [d.element] : []; }); - const drawing_enter = drawing - .enter() - .append('text') - .attr('class', 'text_element noselect'); + const drawing_enter = drawing.enter().append('text').attr('class', 'text_element noselect'); const merge = drawing.merge(drawing_enter); merge @@ -40,8 +36,8 @@ export class TextDrawingWidget implements DrawingShapeWidget { } return styles.join('; '); }) - .attr('fill', text => text.fill) - .attr('text-decoration', text => text.text_decoration); + .attr('fill', (text) => text.fill) + .attr('text-decoration', (text) => text.text_decoration); const lines = merge.selectAll('tspan').data((text: TextElement) => { return text.text.split(/\r?\n/); @@ -52,14 +48,14 @@ export class TextDrawingWidget implements DrawingShapeWidget { const lines_merge = lines.merge(lines_enter); lines_merge - .text(line => line) + .text((line) => line) .attr('xml:space', 'preserve') .attr('x', 0) .attr('dy', (line, i) => (i === 0 ? '0em' : '1.4em')); lines.exit().remove(); - merge.attr('transform', function(this: SVGTextElement) { + merge.attr('transform', function (this: SVGTextElement) { // SVG calculates y pos by the /bottom/ of the first tspan, hence we need to make some // approx and make it matching to GUI const tspan = select(this).selectAll('tspan'); diff --git a/src/app/cartography/widgets/graph-layout.ts b/src/app/cartography/widgets/graph-layout.ts index ab100626..aa62ed35 100644 --- a/src/app/cartography/widgets/graph-layout.ts +++ b/src/app/cartography/widgets/graph-layout.ts @@ -1,13 +1,13 @@ +import { Injectable } from '@angular/core'; +import { LayersManager } from '../managers/layers-manager'; import { Context } from '../models/context'; +import { SVGSelection } from '../models/types'; +import { MovingTool } from '../tools/moving-tool'; +import { SelectionTool } from '../tools/selection-tool'; +import { DrawingLineWidget } from './drawing-line'; +import { LayersWidget } from './layers'; import { NodesWidget } from './nodes'; import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { DrawingLineWidget } from './drawing-line'; -import { SelectionTool } from '../tools/selection-tool'; -import { MovingTool } from '../tools/moving-tool'; -import { LayersWidget } from './layers'; -import { LayersManager } from '../managers/layers-manager'; -import { Injectable } from '@angular/core'; @Injectable() export class GraphLayout implements Widget { @@ -33,10 +33,7 @@ export class GraphLayout implements Widget { } connect(view: SVGSelection, context: Context) { - this.drawingLineTool.connect( - view, - context - ); + this.drawingLineTool.connect(view, context); } draw(view: SVGSelection, context: Context) { @@ -44,10 +41,7 @@ export class GraphLayout implements Widget { const canvas = view.selectAll('g.canvas').data([context]); - const canvasEnter = canvas - .enter() - .append('g') - .attr('class', 'canvas'); + const canvasEnter = canvas.enter().append('g').attr('class', 'canvas'); canvas.merge(canvasEnter).attr('transform', (ctx: Context) => { const xTrans = ctx.getZeroZeroTransformationPoint().x + ctx.transformation.x; diff --git a/src/app/cartography/widgets/interface-label.spec.ts b/src/app/cartography/widgets/interface-label.spec.ts index 180f25aa..2bc80598 100644 --- a/src/app/cartography/widgets/interface-label.spec.ts +++ b/src/app/cartography/widgets/interface-label.spec.ts @@ -1,15 +1,14 @@ import { Selection } from 'd3-selection'; - -import { TestSVGCanvas } from '../testing'; -import { InterfaceLabelWidget } from './interface-label'; import { CssFixer } from '../helpers/css-fixer'; -import { MapNode } from '../models/map/map-node'; +import { FontFixer } from '../helpers/font-fixer'; +import { MapSettingsManager } from '../managers/map-settings-manager'; +import { SelectionManager } from '../managers/selection-manager'; +import { MapLabel } from '../models/map/map-label'; import { MapLink } from '../models/map/map-link'; import { MapLinkNode } from '../models/map/map-link-node'; -import { MapLabel } from '../models/map/map-label'; -import { FontFixer } from '../helpers/font-fixer'; -import { SelectionManager } from '../managers/selection-manager'; -import { MapSettingsManager } from '../managers/map-settings-manager'; +import { MapNode } from '../models/map/map-node'; +import { TestSVGCanvas } from '../testing'; +import { InterfaceLabelWidget } from './interface-label'; describe('InterfaceLabelsWidget', () => { let svg: TestSVGCanvas; @@ -58,10 +57,7 @@ describe('InterfaceLabelsWidget', () => { const linksSelection = svg.canvas.selectAll('g.link').data(links); - linksEnter = linksSelection - .enter() - .append('g') - .attr('class', 'link'); + linksEnter = linksSelection.enter().append('g').attr('class', 'link'); linksSelection.exit().remove(); diff --git a/src/app/cartography/widgets/interface-label.ts b/src/app/cartography/widgets/interface-label.ts index 7adcb0e2..c6060978 100644 --- a/src/app/cartography/widgets/interface-label.ts +++ b/src/app/cartography/widgets/interface-label.ts @@ -1,16 +1,15 @@ -import { Injectable, EventEmitter } from '@angular/core'; - -import { SVGSelection } from '../models/types'; -import { CssFixer } from '../helpers/css-fixer'; +import { EventEmitter, Injectable } from '@angular/core'; import { select } from 'd3-selection'; -import { MapLink } from '../models/map/map-link'; +import { Draggable } from '../events/draggable'; +import { InterfaceLabelContextMenu } from '../events/event-source'; +import { CssFixer } from '../helpers/css-fixer'; import { FontFixer } from '../helpers/font-fixer'; +import { MapSettingsManager } from '../managers/map-settings-manager'; import { SelectionManager } from '../managers/selection-manager'; +import { MapLink } from '../models/map/map-link'; import { MapLinkNode } from '../models/map/map-link-node'; import { MapNode } from '../models/map/map-node'; -import { Draggable } from '../events/draggable'; -import { MapSettingsManager } from '../managers/map-settings-manager'; -import { InterfaceLabelContextMenu } from '../events/event-source'; +import { SVGSelection } from '../models/types'; @Injectable() export class InterfaceLabelWidget { @@ -36,7 +35,10 @@ export class InterfaceLabelWidget { const link_node_position = selection .selectAll('g.link_node_position') - .data((link: MapLink) => [[link.source, link.nodes[0]], [link.target, link.nodes[1]]]); + .data((link: MapLink) => [ + [link.source, link.nodes[0]], + [link.target, link.nodes[1]], + ]); const enter_link_node_position = link_node_position .enter() @@ -58,10 +60,7 @@ export class InterfaceLabelWidget { return []; }); - const enter = labels - .enter() - .append('g') - .classed('interface_label_container', true); + const enter = labels.enter().append('g').classed('interface_label_container', true); // create surrounding rect enter.append('rect').attr('class', 'interface_label_selection'); @@ -72,12 +71,10 @@ export class InterfaceLabelWidget { .attr('class', 'interface_label noselect') .attr('interface_label_id', (i: MapLinkNode) => `${i.id}`); - const merge = labels - .merge(enter) - .on('contextmenu', (n: MapLinkNode, i: number) => { - event.preventDefault(); - self.onContextMenu.emit(new InterfaceLabelContextMenu(event, n)); - }); + const merge = labels.merge(enter).on('contextmenu', (n: MapLinkNode, i: number) => { + event.preventDefault(); + self.onContextMenu.emit(new InterfaceLabelContextMenu(event, n)); + }); // update label merge @@ -102,7 +99,7 @@ export class InterfaceLabelWidget { .attr('stroke-dasharray', '3,3') .attr('stroke-width', '0.5') .attr('fill', 'none') - .each(function(this: SVGRectElement, l: MapLinkNode) { + .each(function (this: SVGRectElement, l: MapLinkNode) { const current = select(this); const textLabel = merge.select(`text[interface_label_id="${l.id}"]`); const bbox = textLabel.node().getBBox(); diff --git a/src/app/cartography/widgets/interface-status.ts b/src/app/cartography/widgets/interface-status.ts index 7bd3e47c..ebafddcc 100644 --- a/src/app/cartography/widgets/interface-status.ts +++ b/src/app/cartography/widgets/interface-status.ts @@ -1,20 +1,16 @@ import { Injectable } from '@angular/core'; - import { select } from 'd3-selection'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; +import { MapSettingsService } from '../../services/mapsettings.service'; import { LinkStatus } from '../models/link-status'; import { MapLink } from '../models/map/map-link'; -import { MapSettingsService } from '../../services/mapsettings.service'; +import { SVGSelection } from '../models/types'; +import { Widget } from './widget'; @Injectable() export class InterfaceStatusWidget implements Widget { - private mapSettingsService: MapSettingsService + private mapSettingsService: MapSettingsService; - constructor( - private _mapSettingsService: MapSettingsService - ) { + constructor(private _mapSettingsService: MapSettingsService) { this.mapSettingsService = _mapSettingsService; } @@ -22,22 +18,24 @@ export class InterfaceStatusWidget implements Widget { const self = this; let mapLinks: MapLink[] = []; - view.each(function(this: SVGGElement, l: MapLink) { + view.each(function (this: SVGGElement, l: MapLink) { mapLinks.push(l); }); - mapLinks.forEach(mapLink => { - mapLinks.forEach(n => { - if (n.nodes[0].linkId !== mapLink.nodes[0].linkId){ - if ((mapLink.nodes[0].nodeId === n.nodes[0].nodeId && mapLink.nodes[1].nodeId === n.nodes[1].nodeId) || - (mapLink.nodes[0].nodeId === n.nodes[1].nodeId && mapLink.nodes[1].nodeId === n.nodes[0].nodeId) || - (mapLink.nodes[1].nodeId === n.nodes[0].nodeId && mapLink.nodes[0].nodeId === n.nodes[1].nodeId)) { + mapLinks.forEach((mapLink) => { + mapLinks.forEach((n) => { + if (n.nodes[0].linkId !== mapLink.nodes[0].linkId) { + if ( + (mapLink.nodes[0].nodeId === n.nodes[0].nodeId && mapLink.nodes[1].nodeId === n.nodes[1].nodeId) || + (mapLink.nodes[0].nodeId === n.nodes[1].nodeId && mapLink.nodes[1].nodeId === n.nodes[0].nodeId) || + (mapLink.nodes[1].nodeId === n.nodes[0].nodeId && mapLink.nodes[0].nodeId === n.nodes[1].nodeId) + ) { mapLink.isMultiplied = true; } } }); }); - view.each(function(this: SVGGElement, l: MapLink) { + view.each(function (this: SVGGElement, l: MapLink) { const link_group = select(this); const link_path = link_group.select('path'); @@ -48,37 +46,42 @@ export class InterfaceStatusWidget implements Widget { if (link_path.node().getTotalLength() > 2 * 45 + 130) { if (l.source && l.target) { - let sourcePort = l.nodes.find(node => node.nodeId === l.source.id).label.text; - let destinationPort = l.nodes.find(node => node.nodeId === l.target.id).label.text; + let sourcePort = l.nodes.find((node) => node.nodeId === l.source.id).label.text; + let destinationPort = l.nodes.find((node) => node.nodeId === l.target.id).label.text; statuses = [ - new LinkStatus(start_point.x, start_point.y, (l.capturing && l.suspend) ? 'suspended' : l.source.status, sourcePort), - new LinkStatus(end_point.x, end_point.y, (l.capturing && l.suspend) ? 'suspended' : l.target.status, destinationPort) + new LinkStatus( + start_point.x, + start_point.y, + l.capturing && l.suspend ? 'suspended' : l.source.status, + sourcePort + ), + new LinkStatus( + end_point.x, + end_point.y, + l.capturing && l.suspend ? 'suspended' : l.target.status, + destinationPort + ), ]; } } } - link_group - .selectAll('circle.status_started').remove(); - link_group - .selectAll('circle.status_stopped').remove(); - link_group - .selectAll('circle.status_suspended').remove(); + link_group.selectAll('circle.status_started').remove(); + link_group.selectAll('circle.status_stopped').remove(); + link_group.selectAll('circle.status_suspended').remove(); - link_group - .selectAll('rect.status_started').remove(); - link_group - .selectAll('text.status_started_label').remove(); - link_group - .selectAll('rect.status_stopped').remove(); - link_group - .selectAll('text.status_stopped_label').remove(); - link_group - .selectAll('rect.status_suspended').remove(); - link_group - .selectAll('text.status_suspended_label').remove(); + link_group.selectAll('rect.status_started').remove(); + link_group.selectAll('text.status_started_label').remove(); + link_group.selectAll('rect.status_stopped').remove(); + link_group.selectAll('text.status_stopped_label').remove(); + link_group.selectAll('rect.status_suspended').remove(); + link_group.selectAll('text.status_suspended_label').remove(); - if (self.mapSettingsService.showInterfaceLabels && self.mapSettingsService.integrateLinkLabelsToLinks && !l.isMultiplied) { + if ( + self.mapSettingsService.showInterfaceLabels && + self.mapSettingsService.integrateLinkLabelsToLinks && + !l.isMultiplied + ) { const status_started = link_group .selectAll('rect.status_started') .data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started')); @@ -87,7 +90,7 @@ export class InterfaceStatusWidget implements Widget { .merge(status_started_enter) .attr('class', 'status_started') .attr('width', (ls: LinkStatus) => { - return (ls.port.length * 8) + 10; + return ls.port.length * 8 + 10; }) .attr('height', 20) .attr('x', (ls: LinkStatus) => ls.x - 30) @@ -110,7 +113,7 @@ export class InterfaceStatusWidget implements Widget { .attr('y', (ls: LinkStatus) => ls.y + 5) .attr('fill', `black`); status_started_label.exit().remove(); - + const status_stopped = link_group .selectAll('rect.status_stopped') .data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped')); @@ -119,7 +122,7 @@ export class InterfaceStatusWidget implements Widget { .merge(status_stopped_enter) .attr('class', 'status_stopped') .attr('width', (ls: LinkStatus) => { - return (ls.port.length * 8) + 10; + return ls.port.length * 8 + 10; }) .attr('height', 20) .attr('x', (ls: LinkStatus) => ls.x - 30) @@ -151,7 +154,7 @@ export class InterfaceStatusWidget implements Widget { .merge(status_suspended_enter) .attr('class', 'status_suspended') .attr('width', (ls: LinkStatus) => { - return (ls.port.length * 8) + 10; + return ls.port.length * 8 + 10; }) .attr('height', 20) .attr('x', (ls: LinkStatus) => ls.x - 30) diff --git a/src/app/cartography/widgets/label.ts b/src/app/cartography/widgets/label.ts index ca9794ef..3d3b93dc 100644 --- a/src/app/cartography/widgets/label.ts +++ b/src/app/cartography/widgets/label.ts @@ -1,17 +1,15 @@ -import { Injectable, EventEmitter } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; +import { EventEmitter, Injectable } from '@angular/core'; +import { select } from 'd3-selection'; +import { Draggable } from '../events/draggable'; +import { LabelContextMenu } from '../events/event-source'; import { CssFixer } from '../helpers/css-fixer'; import { FontFixer } from '../helpers/font-fixer'; -import { select } from 'd3-selection'; -import { MapNode } from '../models/map/map-node'; -import { SelectionManager } from '../managers/selection-manager'; -import { Draggable } from '../events/draggable'; -import { MapLabel } from '../models/map/map-label'; import { MapSettingsManager } from '../managers/map-settings-manager'; -import { LabelContextMenu } from '../events/event-source'; -import { TextElement } from '../models/drawings/text-element'; +import { SelectionManager } from '../managers/selection-manager'; +import { MapLabel } from '../models/map/map-label'; +import { MapNode } from '../models/map/map-node'; +import { SVGSelection } from '../models/types'; +import { Widget } from './widget'; @Injectable() export class LabelWidget implements Widget { @@ -43,12 +41,10 @@ export class LabelWidget implements Widget { .attr('class', 'label_container') .attr('label_id', (label: MapLabel) => label.id); - const merge = label_view - .merge(label_enter) - .on('contextmenu', (n: MapLabel, i: number) => { - event.preventDefault(); - self.onContextMenu.emit(new LabelContextMenu(event, n)); - }); + const merge = label_view.merge(label_enter).on('contextmenu', (n: MapLabel, i: number) => { + event.preventDefault(); + self.onContextMenu.emit(new LabelContextMenu(event, n)); + }); this.drawLabel(merge); @@ -60,20 +56,16 @@ export class LabelWidget implements Widget { } private drawLabel(view: SVGSelection) { - const label_body = view.selectAll('g.label_body').data(label => [label]); + const label_body = view.selectAll('g.label_body').data((label) => [label]); - const label_body_enter = label_body - .enter() - .append('g') - .attr('class', 'label_body'); + const label_body_enter = label_body.enter().append('g').attr('class', 'label_body'); // add label of node label_body_enter.append('text').attr('class', 'label'); label_body_enter.append('rect').attr('class', 'label_selection'); - const label_body_merge = label_body - .merge(label_body_enter); + const label_body_merge = label_body.merge(label_body_enter); label_body_merge .select('text.label') @@ -93,13 +85,13 @@ export class LabelWidget implements Widget { label_body_merge .select('rect.label_selection') .attr('visibility', (l: MapLabel) => { - return (this.selectionManager.isSelected(l) ? 'visible' : 'hidden') + return this.selectionManager.isSelected(l) ? 'visible' : 'hidden'; }) .attr('stroke', 'black') .attr('stroke-dasharray', '3,3') .attr('stroke-width', '0.5') .attr('fill', 'none') - .each(function(this: SVGRectElement, label: MapLabel) { + .each(function (this: SVGRectElement, label: MapLabel) { const current = select(this); const textLabel = label_body_merge.select(`text[label_id="${label.id}"]`); const bbox = textLabel.node().getBBox(); diff --git a/src/app/cartography/widgets/layers.spec.ts b/src/app/cartography/widgets/layers.spec.ts index 4dfdf830..3994168c 100644 --- a/src/app/cartography/widgets/layers.spec.ts +++ b/src/app/cartography/widgets/layers.spec.ts @@ -1,11 +1,10 @@ -import { instance, mock, when, verify } from 'ts-mockito'; - -import { TestSVGCanvas } from '../testing'; -import { LayersWidget } from './layers'; +import { instance, mock } from 'ts-mockito'; import { Layer } from '../models/layer'; +import { TestSVGCanvas } from '../testing'; +import { DrawingsWidget } from './drawings'; +import { LayersWidget } from './layers'; import { LinksWidget } from './links'; import { NodesWidget } from './nodes'; -import { DrawingsWidget } from './drawings'; describe('LayersWidget', () => { let svg: TestSVGCanvas; diff --git a/src/app/cartography/widgets/layers.ts b/src/app/cartography/widgets/layers.ts index f706db96..938d2943 100644 --- a/src/app/cartography/widgets/layers.ts +++ b/src/app/cartography/widgets/layers.ts @@ -1,12 +1,10 @@ import { Injectable } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { GraphLayout } from './graph-layout'; import { Layer } from '../models/layer'; +import { SVGSelection } from '../models/types'; +import { DrawingsWidget } from './drawings'; import { LinksWidget } from './links'; import { NodesWidget } from './nodes'; -import { DrawingsWidget } from './drawings'; +import { Widget } from './widget'; @Injectable() export class LayersWidget implements Widget { @@ -21,10 +19,7 @@ export class LayersWidget implements Widget { return layer.index.toString(); }); - const layers_enter = layers_selection - .enter() - .append('g') - .attr('class', 'layer'); + const layers_enter = layers_selection.enter().append('g').attr('class', 'layer'); // add container for links layers_enter.append('g').attr('class', 'links'); diff --git a/src/app/cartography/widgets/link.ts b/src/app/cartography/widgets/link.ts index 6deee822..3e9a3334 100644 --- a/src/app/cartography/widgets/link.ts +++ b/src/app/cartography/widgets/link.ts @@ -1,16 +1,15 @@ -import { Injectable, EventEmitter } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { SerialLinkWidget } from './links/serial-link'; -import { EthernetLinkWidget } from './links/ethernet-link'; -import { MultiLinkCalculatorHelper } from '../helpers/multi-link-calculator-helper'; -import { InterfaceLabelWidget } from './interface-label'; -import { InterfaceStatusWidget } from './interface-status'; -import { MapLink } from '../models/map/map-link'; -import { SelectionManager } from '../managers/selection-manager'; +import { EventEmitter, Injectable } from '@angular/core'; import { event } from 'd3-selection'; import { LinkContextMenu } from '../events/event-source'; +import { MultiLinkCalculatorHelper } from '../helpers/multi-link-calculator-helper'; +import { SelectionManager } from '../managers/selection-manager'; +import { MapLink } from '../models/map/map-link'; +import { SVGSelection } from '../models/types'; +import { InterfaceLabelWidget } from './interface-label'; +import { InterfaceStatusWidget } from './interface-status'; +import { EthernetLinkWidget } from './links/ethernet-link'; +import { SerialLinkWidget } from './links/serial-link'; +import { Widget } from './widget'; @Injectable() export class LinkWidget implements Widget { @@ -26,53 +25,71 @@ export class LinkWidget implements Widget { ) {} public draw(view: SVGSelection) { - const link_body = view.selectAll('g.link_body').data(l => [l]); + const link_body = view.selectAll('g.link_body').data((l) => [l]); - const link_body_enter = link_body - .enter() - .append('g') - .attr('class', 'link_body'); + const link_body_enter = link_body.enter().append('g').attr('class', 'link_body'); - const link_body_merge = link_body.merge(link_body_enter).attr('transform', link => { + const link_body_merge = link_body.merge(link_body_enter).attr('transform', (link) => { const translation = this.multiLinkCalculatorHelper.linkTranslation(link.distance, link.source, link.target); return `translate (${translation.dx}, ${translation.dy})`; }); link_body.select('.capture-icon').remove(); link_body - .filter(l => { return l.capturing && !l.suspend && !(l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) + .filter((l) => { + return ( + l.capturing && + !l.suspend && + !(l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss) + ); + }) .append('g') .on('contextmenu', (datum: MapLink) => { const evt = event; this.onContextMenu.emit(new LinkContextMenu(evt, datum)); }) .attr('class', 'capture-icon') - .attr('transform', link => { - return `translate (${(link.source.x + link.target.x)/2 + 24}, ${(link.source.y + link.target.y)/2 + 24}) scale(0.5)` + .attr('transform', (link) => { + return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${ + (link.source.y + link.target.y) / 2 + 24 + }) scale(0.5)`; }) .attr('viewBox', '0 0 20 20') - .append('image') - .attr("xlink:href", "assets/resources/images/inspect.svg"); + .append('image') + .attr('xlink:href', 'assets/resources/images/inspect.svg'); link_body.select('.filter-capture-icon').remove(); link_body - .filter(l => { return l.capturing && !l.suspend && (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) + .filter((l) => { + return ( + l.capturing && + !l.suspend && + (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss) + ); + }) .append('g') .on('contextmenu', (datum: MapLink) => { const evt = event; this.onContextMenu.emit(new LinkContextMenu(evt, datum)); }) .attr('class', 'filter-capture-icon') - .attr('transform', link => { - return `translate (${(link.source.x + link.target.x)/2 + 24}, ${(link.source.y + link.target.y)/2 + 24}) scale(0.5)` + .attr('transform', (link) => { + return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${ + (link.source.y + link.target.y) / 2 + 24 + }) scale(0.5)`; }) .attr('viewBox', '0 0 20 20') - .append('image') - .attr("xlink:href", "assets/resources/images/filter-capture.svg"); + .append('image') + .attr('xlink:href', 'assets/resources/images/filter-capture.svg'); link_body.select('.filter-icon').remove(); link_body - .filter(l => { return !l.capturing && (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) + .filter((l) => { + return ( + !l.capturing && + (l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss) + ); + }) .append('g') .on('contextmenu', (datum: MapLink) => { const evt = event; @@ -81,30 +98,40 @@ export class LinkWidget implements Widget { .attr('class', 'filter-icon') .attr('width', '48px') .attr('height', '48px') - .attr('transform', link => { - return `translate (${(link.source.x + link.target.x)/2 + 24}, ${(link.source.y + link.target.y)/2 + 24}) scale(0.5)` + .attr('transform', (link) => { + return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${ + (link.source.y + link.target.y) / 2 + 24 + }) scale(0.5)`; }) .attr('viewBox', '0 0 20 20') - .append('image') - .attr('width', '48px') - .attr('height', '48px') - .attr("xlink:href", "assets/resources/images/filter.svg"); + .append('image') + .attr('width', '48px') + .attr('height', '48px') + .attr('xlink:href', 'assets/resources/images/filter.svg'); link_body.select('.pause-icon').remove(); link_body - .filter(l => { return l.capturing && l.suspend && !(l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss)}) + .filter((l) => { + return ( + l.capturing && + l.suspend && + !(l.filters.bpf || l.filters.corrupt || l.filters.delay || l.filters.frequency_drop || l.filters.packet_loss) + ); + }) .append('g') .on('contextmenu', (datum: MapLink) => { const evt = event; this.onContextMenu.emit(new LinkContextMenu(evt, datum)); }) .attr('class', 'pause-icon') - .attr('transform', link => { - return `translate (${(link.source.x + link.target.x)/2 + 24}, ${(link.source.y + link.target.y)/2 + 24}) scale(0.5)` + .attr('transform', (link) => { + return `translate (${(link.source.x + link.target.x) / 2 + 24}, ${ + (link.source.y + link.target.y) / 2 + 24 + }) scale(0.5)`; }) .attr('viewBox', '0 0 20 20') - .append('image') - .attr("xlink:href", "assets/resources/images/pause.svg"); + .append('image') + .attr('xlink:href', 'assets/resources/images/pause.svg'); this.serialLinkWidget.draw(link_body_merge); this.ethernetLinkWidget.draw(link_body_merge); diff --git a/src/app/cartography/widgets/links.spec.ts b/src/app/cartography/widgets/links.spec.ts index 1b8c3e72..4f3b1a5f 100644 --- a/src/app/cartography/widgets/links.spec.ts +++ b/src/app/cartography/widgets/links.spec.ts @@ -1,13 +1,12 @@ -import { instance, mock } from 'ts-mockito'; import { Selection } from 'd3-selection'; - -import { TestSVGCanvas } from '../testing'; -import { Layer } from '../models/layer'; -import { LinksWidget } from './links'; -import { LinkWidget } from './link'; +import { instance, mock } from 'ts-mockito'; import { MultiLinkCalculatorHelper } from '../helpers/multi-link-calculator-helper'; -import { MapNode } from '../models/map/map-node'; +import { Layer } from '../models/layer'; import { MapLink } from '../models/map/map-link'; +import { MapNode } from '../models/map/map-node'; +import { TestSVGCanvas } from '../testing'; +import { LinkWidget } from './link'; +import { LinksWidget } from './links'; describe('LinksWidget', () => { let svg: TestSVGCanvas; @@ -46,10 +45,7 @@ describe('LinksWidget', () => { const layersSelection = svg.canvas.selectAll('g.layer').data(layers); - layersEnter = layersSelection - .enter() - .append('g') - .attr('class', 'layer'); + layersEnter = layersSelection.enter().append('g').attr('class', 'layer'); layersSelection.exit().remove(); }); diff --git a/src/app/cartography/widgets/links.ts b/src/app/cartography/widgets/links.ts index 9283ce8b..f6eecce6 100644 --- a/src/app/cartography/widgets/links.ts +++ b/src/app/cartography/widgets/links.ts @@ -1,11 +1,10 @@ import { Injectable } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; import { MultiLinkCalculatorHelper } from '../helpers/multi-link-calculator-helper'; import { Layer } from '../models/layer'; -import { LinkWidget } from './link'; import { MapLink } from '../models/map/map-link'; +import { SVGSelection } from '../models/types'; +import { LinkWidget } from './link'; +import { Widget } from './widget'; @Injectable() export class LinksWidget implements Widget { diff --git a/src/app/cartography/widgets/links/ethernet-link.ts b/src/app/cartography/widgets/links/ethernet-link.ts index d453b149..3de741e0 100644 --- a/src/app/cartography/widgets/links/ethernet-link.ts +++ b/src/app/cartography/widgets/links/ethernet-link.ts @@ -1,19 +1,20 @@ -import { path } from 'd3-path'; import { EventEmitter, Injectable } from '@angular/core'; -import { Widget } from '../widget'; -import { SVGSelection } from '../../models/types'; -import { MapLink } from '../../models/map/map-link'; +import { path } from 'd3-path'; import { LinkContextMenu } from '../../events/event-source'; +import { MapLink } from '../../models/map/map-link'; +import { SVGSelection } from '../../models/types'; +import { Widget } from '../widget'; class EthernetLinkPath { constructor(public source: [number, number], public target: [number, number]) {} } -@Injectable() export class EthernetLinkWidget implements Widget { +@Injectable() +export class EthernetLinkWidget implements Widget { public onContextMenu = new EventEmitter(); constructor() {} - + private linktoEthernetLink(link: MapLink) { return new EthernetLinkPath( [link.source.x + link.source.width / 2, link.source.y + link.source.height / 2], @@ -22,7 +23,7 @@ class EthernetLinkPath { } public draw(view: SVGSelection) { - const link = view.selectAll('path.ethernet_link').data(l => { + const link = view.selectAll('path.ethernet_link').data((l) => { if (l.linkType === 'ethernet') { return [this.linktoEthernetLink(l)]; } @@ -34,7 +35,7 @@ class EthernetLinkPath { .append('path') .attr('class', 'ethernet_link') .on('contextmenu', (datum) => { - let link: MapLink = datum as unknown as MapLink; + let link: MapLink = (datum as unknown) as MapLink; const evt = event; this.onContextMenu.emit(new LinkContextMenu(evt, link)); }); @@ -43,14 +44,14 @@ class EthernetLinkPath { .attr('stroke', '#000') .attr('stroke-width', '2') .on('contextmenu', (datum) => { - let link: MapLink = datum as unknown as MapLink; + let link: MapLink = (datum as unknown) as MapLink; const evt = event; this.onContextMenu.emit(new LinkContextMenu(evt, link)); }); const link_merge = link.merge(link_enter); - link_merge.attr('d', ethernet => { + link_merge.attr('d', (ethernet) => { const line_generator = path(); line_generator.moveTo(ethernet.source[0], ethernet.source[1]); line_generator.lineTo(ethernet.target[0], ethernet.target[1]); diff --git a/src/app/cartography/widgets/links/serial-link.ts b/src/app/cartography/widgets/links/serial-link.ts index cd6d26c9..9fc0e921 100644 --- a/src/app/cartography/widgets/links/serial-link.ts +++ b/src/app/cartography/widgets/links/serial-link.ts @@ -1,10 +1,9 @@ +import { EventEmitter, Injectable } from '@angular/core'; import { path } from 'd3-path'; - -import { Widget } from '../widget'; -import { SVGSelection } from '../../models/types'; -import { MapLink } from '../../models/map/map-link'; -import { Injectable, EventEmitter } from '@angular/core'; import { LinkContextMenu } from '../../events/event-source'; +import { MapLink } from '../../models/map/map-link'; +import { SVGSelection } from '../../models/types'; +import { Widget } from '../widget'; class SerialLinkPath { constructor( @@ -15,19 +14,20 @@ class SerialLinkPath { ) {} } -@Injectable() export class SerialLinkWidget implements Widget { +@Injectable() +export class SerialLinkWidget implements Widget { public onContextMenu = new EventEmitter(); constructor() {} - + private linkToSerialLink(link: MapLink) { const source = { x: link.source.x + link.source.width / 2, - y: link.source.y + link.source.height / 2 + y: link.source.y + link.source.height / 2, }; const target = { x: link.target.x + link.target.width / 2, - y: link.target.y + link.target.height / 2 + y: link.target.y + link.target.height / 2, }; const dx = target.x - source.x; @@ -39,19 +39,19 @@ class SerialLinkPath { const angle_source: [number, number] = [ source.x + dx / 2.0 + 15 * vect_rot[0], - source.y + dy / 2.0 + 15 * vect_rot[1] + source.y + dy / 2.0 + 15 * vect_rot[1], ]; const angle_target: [number, number] = [ target.x - dx / 2.0 - 15 * vect_rot[0], - target.y - dy / 2.0 - 15 * vect_rot[1] + target.y - dy / 2.0 - 15 * vect_rot[1], ]; return new SerialLinkPath([source.x, source.y], angle_source, angle_target, [target.x, target.y]); } public draw(view: SVGSelection) { - const link = view.selectAll('path.serial_link').data(l => { + const link = view.selectAll('path.serial_link').data((l) => { if (l.linkType === 'serial') { return [this.linkToSerialLink(l)]; } @@ -63,19 +63,16 @@ class SerialLinkPath { .append('path') .attr('class', 'serial_link') .on('contextmenu', (datum) => { - let link: MapLink = datum as unknown as MapLink; + let link: MapLink = (datum as unknown) as MapLink; const evt = event; this.onContextMenu.emit(new LinkContextMenu(evt, link)); }); - link_enter - .attr('stroke', '#B22222') - .attr('fill', 'none') - .attr('stroke-width', '2'); + link_enter.attr('stroke', '#B22222').attr('fill', 'none').attr('stroke-width', '2'); const link_merge = link.merge(link_enter); - link_merge.attr('d', serial => { + link_merge.attr('d', (serial) => { const line_generator = path(); line_generator.moveTo(serial.source[0], serial.source[1]); line_generator.lineTo(serial.source_angle[0], serial.source_angle[1]); diff --git a/src/app/cartography/widgets/node.spec.ts b/src/app/cartography/widgets/node.spec.ts index 2f09f543..f8e669e1 100644 --- a/src/app/cartography/widgets/node.spec.ts +++ b/src/app/cartography/widgets/node.spec.ts @@ -1,12 +1,8 @@ -import { TestSVGCanvas } from '../testing'; -import { CssFixer } from '../helpers/css-fixer'; -import { FontFixer } from '../helpers/font-fixer'; -import { NodeWidget } from './node'; -import { MapNode } from '../models/map/map-node'; -import { MapLabel } from '../models/map/map-label'; import { MockedGraphDataManager } from '../managers/graph-data-manager.spec'; -import { GraphDataManager } from '../managers/graph-data-manager'; -import { SelectionManager } from '../managers/selection-manager'; +import { MapLabel } from '../models/map/map-label'; +import { MapNode } from '../models/map/map-node'; +import { TestSVGCanvas } from '../testing'; +import { NodeWidget } from './node'; describe('NodesWidget', () => { let svg: TestSVGCanvas; @@ -42,7 +38,7 @@ describe('NodesWidget', () => { relatedTarget: drewNode, screenY: 1024, screenX: 1024, - view: window + view: window, }) ); diff --git a/src/app/cartography/widgets/node.ts b/src/app/cartography/widgets/node.ts index 27d798d4..fc217f85 100644 --- a/src/app/cartography/widgets/node.ts +++ b/src/app/cartography/widgets/node.ts @@ -1,16 +1,15 @@ -import { Injectable, EventEmitter } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { NodeContextMenu, NodeClicked } from '../events/nodes'; -import { select, event } from 'd3-selection'; -import { MapNode } from '../models/map/map-node'; +import { EventEmitter, Injectable } from '@angular/core'; +import { event, select } from 'd3-selection'; +import { MapSettingsService } from '../../services/mapsettings.service'; +import { ClickedDataEvent } from '../events/event-source'; +import { NodeClicked, NodeContextMenu } from '../events/nodes'; +import { NodesEventSource } from '../events/nodes-event-source'; import { GraphDataManager } from '../managers/graph-data-manager'; import { SelectionManager } from '../managers/selection-manager'; +import { MapNode } from '../models/map/map-node'; +import { SVGSelection } from '../models/types'; import { LabelWidget } from './label'; -import { NodesEventSource } from '../events/nodes-event-source'; -import { ClickedDataEvent } from '../events/event-source'; -import { MapSettingsService } from '../../services/mapsettings.service'; +import { Widget } from './widget'; @Injectable() export class NodeWidget implements Widget { @@ -29,12 +28,9 @@ export class NodeWidget implements Widget { public draw(view: SVGSelection) { const self = this; - const node_body = view.selectAll('g.node_body').data(n => [n]); + const node_body = view.selectAll('g.node_body').data((n) => [n]); - const node_body_enter = node_body - .enter() - .append('g') - .attr('class', 'node_body'); + const node_body_enter = node_body.enter().append('g').attr('class', 'node_body'); node_body_enter.append('image'); @@ -52,8 +48,8 @@ export class NodeWidget implements Widget { .attr('class', 'layer_label_wrapper') .attr('width', '26') .attr('height', '26') - .attr('x', (n: MapNode) => n.width/2 - 13) - .attr('y', (n: MapNode) => n.height/2 - 13) + .attr('x', (n: MapNode) => n.width / 2 - 13) + .attr('y', (n: MapNode) => n.height / 2 - 13) .attr('fill', 'red'); } @@ -62,13 +58,15 @@ export class NodeWidget implements Widget { node_body_merge .append('text') .attr('class', 'layer_label') - .text((n: MapNode) => { return n.z}) - .attr('x', function(n: MapNode) { - if(n.z >= 100 ) return n.width/2 - 13 - else if(n.z >= 10 ) return n.width/2 - 9 - else return n.width/2 - 5 + .text((n: MapNode) => { + return n.z; }) - .attr('y', (n: MapNode) => n.height/2 + 5) + .attr('x', function (n: MapNode) { + if (n.z >= 100) return n.width / 2 - 13; + else if (n.z >= 10) return n.width / 2 - 9; + else return n.width / 2 - 5; + }) + .attr('y', (n: MapNode) => n.height / 2 + 5) .attr('style', () => { const styles: string[] = []; styles.push(`font-family: "Noto Sans"`); @@ -82,42 +80,38 @@ export class NodeWidget implements Widget { // update image of node node_body_merge .select('image') - .on('contextmenu', function(n: MapNode, i: number) { + .on('contextmenu', function (n: MapNode, i: number) { event.preventDefault(); self.onContextMenu.emit(new NodeContextMenu(event, n)); }) - .on('dblclick', function(n: MapNode, i: number) { + .on('dblclick', function (n: MapNode, i: number) { event.preventDefault(); self.onContextConsoleMenu.emit(new NodeContextMenu(event, n)); }) .attr('xnode:href', (n: MapNode) => n.symbolUrl) .attr('width', (n: MapNode) => { - if (n.nodeType === 'cloud' || n.nodeType === 'nat') return 120; if (!n.width) return 60; - if (n.width > 64) return 64; return n.width; }) .attr('height', (n: MapNode) => { - if (n.nodeType === 'cloud' || n.nodeType === 'nat') return 60; if (!n.height) return 60; - if (n.height > 64) return 64; return n.height; }) .attr('x', (n: MapNode) => { - return 0 + return 0; }) .attr('y', (n: MapNode) => { - return 0 + return 0; }) - .on('mouseover', function(this, n: MapNode) { + .on('mouseover', function (this, n: MapNode) { select(this).attr('class', 'over'); }) - .on('mouseout', function(this, n: MapNode) { + .on('mouseout', function (this, n: MapNode) { select(this).attr('class', ''); }); node_body_merge.attr('transform', (n: MapNode) => { - if (!n.width) return `translate(${n.x - 30},${n.y - 30})` + if (!n.width) return `translate(${n.x - 30},${n.y - 30})`; return `translate(${n.x},${n.y})`; }); diff --git a/src/app/cartography/widgets/nodes.spec.ts b/src/app/cartography/widgets/nodes.spec.ts index 8d0983c2..f0445712 100644 --- a/src/app/cartography/widgets/nodes.spec.ts +++ b/src/app/cartography/widgets/nodes.spec.ts @@ -1,8 +1,8 @@ -import { TestSVGCanvas } from '../testing'; -import { NodesWidget } from './nodes'; -import { NodeWidget } from './node'; import { instance, mock } from 'ts-mockito'; import { MapSettingsManager } from '../managers/map-settings-manager'; +import { TestSVGCanvas } from '../testing'; +import { NodeWidget } from './node'; +import { NodesWidget } from './nodes'; describe('NodesWidget', () => { let svg: TestSVGCanvas; diff --git a/src/app/cartography/widgets/nodes.ts b/src/app/cartography/widgets/nodes.ts index 45b18831..960d5232 100644 --- a/src/app/cartography/widgets/nodes.ts +++ b/src/app/cartography/widgets/nodes.ts @@ -1,12 +1,11 @@ import { Injectable } from '@angular/core'; - -import { Widget } from './widget'; -import { SVGSelection } from '../models/types'; -import { Layer } from '../models/layer'; -import { NodeWidget } from './node'; import { Draggable } from '../events/draggable'; -import { MapNode } from '../models/map/map-node'; import { MapSettingsManager } from '../managers/map-settings-manager'; +import { Layer } from '../models/layer'; +import { MapNode } from '../models/map/map-node'; +import { SVGSelection } from '../models/types'; +import { NodeWidget } from './node'; +import { Widget } from './widget'; @Injectable() export class NodesWidget implements Widget { diff --git a/src/app/common/error-handlers/sentry-error-handler.ts b/src/app/common/error-handlers/sentry-error-handler.ts index 4644a117..d9d31bcf 100644 --- a/src/app/common/error-handlers/sentry-error-handler.ts +++ b/src/app/common/error-handlers/sentry-error-handler.ts @@ -1,15 +1,11 @@ -import { BrowserModule } from "@angular/platform-browser"; -import { NgModule, ErrorHandler, Injectable, Injector, Inject } from "@angular/core"; -import { HttpErrorResponse } from "@angular/common/http"; - -import { environment } from "../../../environments/environment"; -import { AppComponent } from "../../app.component"; - -import * as Sentry from "@sentry/browser"; +import { HttpErrorResponse } from '@angular/common/http'; +import { ErrorHandler, Inject, Injectable, Injector } from '@angular/core'; +import * as Sentry from '@sentry/browser'; import { BrowserOptions, init } from '@sentry/browser'; +import { environment } from '../../../environments/environment'; const config = { - dsn: "https://d8be3a98530f49eb90968ff396db326c@o19455.ingest.sentry.io/842726" + dsn: 'https://d8be3a98530f49eb90968ff396db326c@o19455.ingest.sentry.io/842726', }; init(config as BrowserOptions); @@ -25,7 +21,7 @@ export class SentryErrorHandler implements ErrorHandler { } // We can handle messages and Error objects directly. - if (typeof error === "string" || error instanceof Error) { + if (typeof error === 'string' || error instanceof Error) { return error; } @@ -42,7 +38,7 @@ export class SentryErrorHandler implements ErrorHandler { } // ...or the request body itself, which we can use as a message instead. - if (typeof error.error === "string") { + if (typeof error.error === 'string') { return `Server returned code ${error.status} with body "${error.error}"`; } @@ -55,7 +51,7 @@ export class SentryErrorHandler implements ErrorHandler { } handleError(error) { - let extractedError = this.extractError(error) || "Handled unknown error"; + let extractedError = this.extractError(error) || 'Handled unknown error'; // Capture handled exception and send it to Sentry. const eventId = Sentry.captureException(extractedError); diff --git a/src/app/common/error-handlers/toaster-error-handler.spec.ts b/src/app/common/error-handlers/toaster-error-handler.spec.ts index 9876b5d2..199b114f 100644 --- a/src/app/common/error-handlers/toaster-error-handler.spec.ts +++ b/src/app/common/error-handlers/toaster-error-handler.spec.ts @@ -1,11 +1,11 @@ +import { Injector } from '@angular/core'; import { TestBed } from '@angular/core/testing'; -import { ToasterService } from '../../services/toaster.service'; -import { MockedToasterService } from '../../services/toaster.service.spec'; -import { ToasterErrorHandler } from './toaster-error-handler'; import { SettingsService } from '../../services/settings.service'; import { MockedSettingsService } from '../../services/settings.service.spec'; -import { Injector } from '@angular/core'; +import { ToasterService } from '../../services/toaster.service'; +import { MockedToasterService } from '../../services/toaster.service.spec'; import { SentryErrorHandler } from './sentry-error-handler'; +import { ToasterErrorHandler } from './toaster-error-handler'; class MockedToasterErrorHandler extends ToasterErrorHandler { handleError(err: any): void { @@ -24,8 +24,8 @@ describe('ToasterErrorHandler', () => { { provide: ToasterService, useClass: MockedToasterService }, { provide: SettingsService, useClass: MockedSettingsService }, SentryErrorHandler, - ToasterErrorHandler - ] + ToasterErrorHandler, + ], }); handler = new MockedToasterErrorHandler(TestBed.get(Injector)); diff --git a/src/app/common/error-handlers/toaster-error-handler.ts b/src/app/common/error-handlers/toaster-error-handler.ts index 2cba24e2..54549731 100644 --- a/src/app/common/error-handlers/toaster-error-handler.ts +++ b/src/app/common/error-handlers/toaster-error-handler.ts @@ -1,16 +1,20 @@ +import { Injectable } from '@angular/core'; import { ToasterService } from '../../services/toaster.service'; -import { Injectable } from "@angular/core"; import { SentryErrorHandler } from './sentry-error-handler'; @Injectable() export class ToasterErrorHandler extends SentryErrorHandler { handleError(err: any): void { - if (err.error && err.error.status && !(err.error.status === 400 || err.error.status === 403 || err.error.status === 404 || err.error.status === 409)) { + if ( + err.error && + err.error.status && + !(err.error.status === 400 || err.error.status === 403 || err.error.status === 404 || err.error.status === 409) + ) { super.handleError(err); } if (!err) return; - + const toasterService = this.injector.get(ToasterService); if (err.error && err.error.message) { toasterService.error(err.error.message); diff --git a/src/app/common/progress-dialog/progress-dialog.component.spec.ts b/src/app/common/progress-dialog/progress-dialog.component.spec.ts index c1694de4..cf08db74 100644 --- a/src/app/common/progress-dialog/progress-dialog.component.spec.ts +++ b/src/app/common/progress-dialog/progress-dialog.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { ProgressDialogComponent } from './progress-dialog.component'; describe('ProgressDialogComponent', () => { @@ -8,7 +7,7 @@ describe('ProgressDialogComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ProgressDialogComponent] + declarations: [ProgressDialogComponent], }).compileComponents(); })); diff --git a/src/app/common/progress-dialog/progress-dialog.component.ts b/src/app/common/progress-dialog/progress-dialog.component.ts index 099907c7..a27152c7 100644 --- a/src/app/common/progress-dialog/progress-dialog.component.ts +++ b/src/app/common/progress-dialog/progress-dialog.component.ts @@ -1,10 +1,10 @@ import { Component, Inject, OnInit } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ selector: 'app-progress-dialog', templateUrl: './progress-dialog.component.html', - styleUrls: ['./progress-dialog.component.scss'] + styleUrls: ['./progress-dialog.component.scss'], }) export class ProgressDialogComponent implements OnInit { public static CANCELLED: 'canceled'; diff --git a/src/app/common/progress-dialog/progress-dialog.service.spec.ts b/src/app/common/progress-dialog/progress-dialog.service.spec.ts index 20348669..86b6ba0f 100644 --- a/src/app/common/progress-dialog/progress-dialog.service.spec.ts +++ b/src/app/common/progress-dialog/progress-dialog.service.spec.ts @@ -1,11 +1,10 @@ -import { TestBed, inject } from '@angular/core/testing'; - +import { TestBed } from '@angular/core/testing'; import { ProgressDialogService } from './progress-dialog.service'; describe('ProgressDialogService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [ProgressDialogService] + providers: [ProgressDialogService], }); }); diff --git a/src/app/common/progress-dialog/progress-dialog.service.ts b/src/app/common/progress-dialog/progress-dialog.service.ts index 925f5217..1454cc14 100644 --- a/src/app/common/progress-dialog/progress-dialog.service.ts +++ b/src/app/common/progress-dialog/progress-dialog.service.ts @@ -10,7 +10,7 @@ export class ProgressDialogService { const ref = this.dialog.open(ProgressDialogComponent, { width: '250px', autoFocus: false, - disableClose: true + disableClose: true, }); return ref; } diff --git a/src/app/common/progress/progress.component.html b/src/app/common/progress/progress.component.html index 9f5aede6..c2e641e6 100644 --- a/src/app/common/progress/progress.component.html +++ b/src/app/common/progress/progress.component.html @@ -4,8 +4,12 @@
error_outline
Error occurred: {{ error.message }}
- - + +
diff --git a/src/app/common/progress/progress.component.spec.ts b/src/app/common/progress/progress.component.spec.ts index b56fe900..368de1e8 100644 --- a/src/app/common/progress/progress.component.spec.ts +++ b/src/app/common/progress/progress.component.spec.ts @@ -1,12 +1,11 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ProgressComponent } from './progress.component'; import { MatIconModule } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { ProgressService } from './progress.service'; -import { RouterTestingModule } from '@angular/router/testing'; import { Router } from '@angular/router'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { RouterTestingModule } from '@angular/router/testing'; +import { BehaviorSubject } from 'rxjs'; +import { ProgressComponent } from './progress.component'; +import { ProgressService } from './progress.service'; export class MockedRouter { events: BehaviorSubject; @@ -28,7 +27,7 @@ describe('ProgressComponent', () => { TestBed.configureTestingModule({ imports: [RouterTestingModule, MatProgressSpinnerModule, MatIconModule], providers: [ProgressService, { provide: Router, useValue: router }], - declarations: [ProgressComponent] + declarations: [ProgressComponent], }).compileComponents(); progressService = TestBed.get(ProgressService); @@ -59,7 +58,7 @@ describe('ProgressComponent', () => { }); it('should set error state when error defined', () => { - const error = {error: 'test'}; + const error = { error: 'test' }; progressService.setError(error); expect(component.error).toEqual(error.error); }); @@ -75,7 +74,7 @@ describe('ProgressComponent', () => { expect(progressService.clear).toHaveBeenCalled(); }); - it("should reload page after clicking refresh", () => { + it('should reload page after clicking refresh', () => { spyOn(router, 'navigateByUrl'); component.refresh(); diff --git a/src/app/common/progress/progress.component.ts b/src/app/common/progress/progress.component.ts index b9ce8f91..e554d232 100644 --- a/src/app/common/progress/progress.component.ts +++ b/src/app/common/progress/progress.component.ts @@ -1,12 +1,12 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { ProgressService } from './progress.service'; import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; +import { ProgressService } from './progress.service'; @Component({ selector: 'app-progress', templateUrl: './progress.component.html', - styleUrls: ['./progress.component.scss'] + styleUrls: ['./progress.component.scss'], }) export class ProgressComponent implements OnInit, OnDestroy { visible = false; @@ -16,7 +16,7 @@ export class ProgressComponent implements OnInit, OnDestroy { constructor(private progressService: ProgressService, private router: Router) {} ngOnInit() { - this.progressService.state.subscribe(state => { + this.progressService.state.subscribe((state) => { this.visible = state.visible; // only set error state once; ignore next "correct" states diff --git a/src/app/common/progress/progress.service.spec.ts b/src/app/common/progress/progress.service.spec.ts index 23a76f08..efdf1989 100644 --- a/src/app/common/progress/progress.service.spec.ts +++ b/src/app/common/progress/progress.service.spec.ts @@ -1,5 +1,4 @@ -import { TestBed, inject } from '@angular/core/testing'; - +import { TestBed } from '@angular/core/testing'; import { ProgressService, State } from './progress.service'; describe('ProgressService', () => { @@ -7,7 +6,7 @@ describe('ProgressService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [ProgressService] + providers: [ProgressService], }); progressService = TestBed.get(ProgressService); @@ -30,7 +29,7 @@ describe('ProgressService', () => { }); it('should propagate event on error', () => { - const error = {error: 'Error'}; + const error = { error: 'Error' }; progressService.setError(error); expect(progressService.state.next).toHaveBeenCalledWith(new State(false, error.error)); }); diff --git a/src/app/common/progress/progress.service.ts b/src/app/common/progress/progress.service.ts index 45895536..b9b52fde 100644 --- a/src/app/common/progress/progress.service.ts +++ b/src/app/common/progress/progress.service.ts @@ -1,5 +1,4 @@ import { Injectable } from '@angular/core'; - import { BehaviorSubject } from 'rxjs'; export class State { diff --git a/src/app/components/adbutler/adbutler.component.html b/src/app/components/adbutler/adbutler.component.html index 2885bcf5..7a714376 100644 --- a/src/app/components/adbutler/adbutler.component.html +++ b/src/app/components/adbutler/adbutler.component.html @@ -1 +1,11 @@ -
+
+ + close +
diff --git a/src/app/components/adbutler/adbutler.component.scss b/src/app/components/adbutler/adbutler.component.scss index a72c224a..932aa606 100644 --- a/src/app/components/adbutler/adbutler.component.scss +++ b/src/app/components/adbutler/adbutler.component.scss @@ -1,30 +1,58 @@ .ad { - background-color: transparent; - width: 400px; + position: fixed; + left: 0; + right: 0; + bottom: 0; + background-color: #a8ecff; padding-top: 10px; padding-bottom: 10px; font-size: 12px; + font-weight: bold; + opacity: 0.8; +} + +.adInnerContainer { + margin: auto; + text-align: center; +} + +.adBody { + padding-right: 16px; +} + +.close-button { + position: absolute; + top: 15px; + right: 15px; + color: #000 !important; +} + +.lightTheme { + background-color: #ddf9ff; +} + +.hidden { + visibility: hidden; } button { - background-color: #0097a7; + background-color: #01d4ff; margin-top: 2px; border: none; outline: none; padding: 5px; color: white; font-weight: bold; + font-size: 11px; padding-right: 15px; padding-left: 15px; - border-radius: 4px; -} + border-radius: 6px; -a { - color: #0097a7; -} - -button { a { color: white; } } + +a { + color: #122124; +} diff --git a/src/app/components/adbutler/adbutler.component.spec.ts b/src/app/components/adbutler/adbutler.component.spec.ts index 1aa8070f..15ff30f3 100644 --- a/src/app/components/adbutler/adbutler.component.spec.ts +++ b/src/app/components/adbutler/adbutler.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { AdbutlerComponent } from './adbutler.component'; xdescribe('AdbutlerComponent', () => { @@ -8,9 +7,8 @@ xdescribe('AdbutlerComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ AdbutlerComponent ] - }) - .compileComponents(); + declarations: [AdbutlerComponent], + }).compileComponents(); })); beforeEach(() => { diff --git a/src/app/components/adbutler/adbutler.component.ts b/src/app/components/adbutler/adbutler.component.ts index 00fc439f..59e6ae3f 100644 --- a/src/app/components/adbutler/adbutler.component.ts +++ b/src/app/components/adbutler/adbutler.component.ts @@ -1,47 +1,68 @@ -import { Component, OnInit, ElementRef, ViewChild, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core'; import { HttpClient } from '@angular/common/http'; +import { Component, OnInit } from '@angular/core'; import { AdButlerResponse } from '../../models/adbutler'; -import { ToasterService } from '../../services/toaster.service'; +import { ThemeService } from '../../services/theme.service'; +import { Location } from '@angular/common'; + +const adButlerResponseBodyRegex: RegExp = /(.*)<\/a>(.*)\s*`; + isVisible: boolean = false; + isLightThemeEnabled: boolean = false; - constructor( - private httpClient: HttpClient - ) {} + // Default ad props in case adbutler request fails + adUrl: string = + 'https://try.solarwinds.com/gns3-free-toolset-giveaway?CMP=LEC-HAD-GNS3-SW_NA_X_NP_X_X_EN_STSGA_SW-ST-20200901_ST_OF1_TRY-NWSLTR'; + adBody: string = + 'Network Config Generator makes it easy configure network devices, including VLANs without opening the CLI'; + buttonLabel: string = 'Check it out!'; + + constructor(private httpClient: HttpClient, private themeService: ThemeService, private location: Location) {} + + hide() { + this.isVisible = false; + } ngOnInit() { + if (this.location.path().includes('nodes')) return; this.httpClient - .get('https://servedbyadbutler.com/adserve/;ID=165803;size=0x0;setID=371476;type=json;').subscribe( - response => { - if (response && response['placements'] && response['placements'].placement_1 && response['placements'].placement_1.body) { - this.onLoad.emit(true); - this.htmlCode = response['placements'].placement_1.body; - this.ad.nativeElement.insertAdjacentHTML('beforeend', this.htmlCode); - } else { - this.onLoad.emit(true); - this.htmlCode = this.staticCode; + .get('https://servedbyadbutler.com/adserve/;ID=165803;size=0x0;setID=371476;type=json;') + .subscribe( + (response) => { + if (response?.placements?.placement_1?.body) { + try { + // Use a regexp to parse the AdButler response. Preferably we would use the AdButler API + // directly to get the data we need through a JSON response, but making an API request + // involves storing credentials, which would be unwise to store in this repo. Best thing + // would to have gns3.com proxy the JSON ad data to this web ui app. + const htmlWithoutNewlines = response.placements.placement_1.body.replace(/(\r\n|\n|\r)/gm, ''); + const parsedAdResponseParts = adButlerResponseBodyRegex.exec(htmlWithoutNewlines); + + // Ad title (2nd capture group) currently not used + this.adUrl = parsedAdResponseParts[1].trim(); + this.adBody = parsedAdResponseParts[3].trim(); + this.buttonLabel = parsedAdResponseParts[4].trim(); + } catch (e) {} } + + this.isVisible = true; }, - error => {} + (error) => {} ); + + this.themeService.getActualTheme() === 'light' + ? (this.isLightThemeEnabled = true) + : (this.isLightThemeEnabled = false); + + this.themeService.themeChanged.subscribe(() => { + this.themeService.getActualTheme() === 'light' + ? (this.isLightThemeEnabled = true) + : (this.isLightThemeEnabled = false); + }); } } diff --git a/src/app/components/bundled-server-finder/bundled-server-finder.component.spec.ts b/src/app/components/bundled-server-finder/bundled-server-finder.component.spec.ts index 872561ca..8d4d16de 100644 --- a/src/app/components/bundled-server-finder/bundled-server-finder.component.spec.ts +++ b/src/app/components/bundled-server-finder/bundled-server-finder.component.spec.ts @@ -1,14 +1,12 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { Router } from '@angular/router'; - -import { BundledServerFinderComponent } from './bundled-server-finder.component'; +import { ProgressService } from '../../common/progress/progress.service'; +import { Server } from '../../models/server'; import { ServerService } from '../../services/server.service'; import { MockedServerService } from '../../services/server.service.spec'; -import { Server } from '../../models/server'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { ProgressService } from '../../common/progress/progress.service'; import { MockedProgressService } from '../project-map/project-map.component.spec'; - +import { BundledServerFinderComponent } from './bundled-server-finder.component'; describe('BundledServerFinderComponent', () => { let component: BundledServerFinderComponent; @@ -19,7 +17,7 @@ describe('BundledServerFinderComponent', () => { beforeEach(async(() => { router = { - navigate: jasmine.createSpy('navigate') + navigate: jasmine.createSpy('navigate'), }; const server = new Server(); @@ -32,10 +30,10 @@ describe('BundledServerFinderComponent', () => { providers: [ { provide: Router, useValue: router }, { provide: ServerService, useValue: serverService }, - { provide: ProgressService, useValue: progressService } + { provide: ProgressService, useValue: progressService }, ], declarations: [BundledServerFinderComponent], - schemas: [NO_ERRORS_SCHEMA] + schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); fixture = TestBed.createComponent(BundledServerFinderComponent); diff --git a/src/app/components/bundled-server-finder/bundled-server-finder.component.ts b/src/app/components/bundled-server-finder/bundled-server-finder.component.ts index 25b86953..9fea4c8e 100644 --- a/src/app/components/bundled-server-finder/bundled-server-finder.component.ts +++ b/src/app/components/bundled-server-finder/bundled-server-finder.component.ts @@ -1,38 +1,32 @@ -import { Component, OnInit, Inject } from '@angular/core'; -import { Router } from '@angular/router'; - -import { ServerService } from '../../services/server.service'; -import { Server } from '../../models/server'; import { DOCUMENT } from '@angular/common'; +import { Component, Inject, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; import { ProgressService } from '../../common/progress/progress.service'; +import { Server } from '../../models/server'; +import { ServerService } from '../../services/server.service'; @Component({ selector: 'app-bundled-server-finder', templateUrl: './bundled-server-finder.component.html', - styleUrls: ['./bundled-server-finder.component.scss'] + styleUrls: ['./bundled-server-finder.component.scss'], }) export class BundledServerFinderComponent implements OnInit { constructor( private router: Router, private serverService: ServerService, private progressService: ProgressService, - @Inject(DOCUMENT) private document) {} + @Inject(DOCUMENT) private document + ) {} ngOnInit() { this.progressService.activate(); - setTimeout(() => - { + setTimeout(() => { let port = parseInt(this.document.location.port, 10) ? parseInt(this.document.location.port, 10) : 80; - this.serverService.getLocalServer( - this.document.location.hostname, - port - ) - .then((server: Server) => { + this.serverService.getLocalServer(this.document.location.hostname, port).then((server: Server) => { this.progressService.deactivate(); this.router.navigate(['/server', server.id, 'projects']); }); - }, - 100); + }, 100); } } diff --git a/src/app/components/dialogs/information-dialog.component.ts b/src/app/components/dialogs/information-dialog.component.ts index 9d58b7e9..b5f6da02 100644 --- a/src/app/components/dialogs/information-dialog.component.ts +++ b/src/app/components/dialogs/information-dialog.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, Inject } from '@angular/core'; -import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { Component, OnInit } from '@angular/core'; +import { MatDialogRef } from '@angular/material/dialog'; @Component({ selector: 'app-information-dialog', templateUrl: 'information-dialog.component.html', - styleUrls: ['information-dialog.component.scss'] + styleUrls: ['information-dialog.component.scss'], }) export class InformationDialogComponent implements OnInit { public confirmationMessage: string; diff --git a/src/app/components/direct-link/direct-link.component.ts b/src/app/components/direct-link/direct-link.component.ts index b85eac28..5d3e957d 100644 --- a/src/app/components/direct-link/direct-link.component.ts +++ b/src/app/components/direct-link/direct-link.component.ts @@ -1,15 +1,15 @@ -import { Component, OnInit, ElementRef, ViewChild, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core'; -import { ServerService } from '../../services/server.service'; -import { ServerDatabase } from '../../services/server.database'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; import { Server } from '../../models/server'; +import { ServerDatabase } from '../../services/server.database'; +import { ServerService } from '../../services/server.service'; import { ToasterService } from '../../services/toaster.service'; @Component({ selector: 'app-direct-link', templateUrl: './direct-link.component.html', styleUrls: ['./direct-link.component.scss'], - encapsulation: ViewEncapsulation.None + encapsulation: ViewEncapsulation.None, }) export class DirectLinkComponent implements OnInit { constructor( @@ -36,20 +36,20 @@ export class DirectLinkComponent implements OnInit { const projectId = this.route.snapshot.paramMap.get('project_id'); const servers = await this.serverService.findAll(); - const server = servers.filter(server => server.host === serverIp && server.port === serverPort)[0]; + const server = servers.filter((server) => server.host === serverIp && server.port === serverPort)[0]; if (server) { - this.router.navigate(['/server', server.id, 'project', projectId]); - } else { - let serverToAdd: Server = new Server(); - serverToAdd.host = serverIp; - serverToAdd.port = serverPort; - serverToAdd.location = 'bundled'; - serverToAdd.name = serverIp; + this.router.navigate(['/server', server.id, 'project', projectId]); + } else { + let serverToAdd: Server = new Server(); + serverToAdd.host = serverIp; + serverToAdd.port = serverPort; + serverToAdd.location = 'bundled'; + serverToAdd.name = serverIp; - this.serverService.create(serverToAdd).then((addedServer: Server) => { - this.router.navigate(['/server', addedServer.id, 'project', projectId]); - }); + this.serverService.create(serverToAdd).then((addedServer: Server) => { + this.router.navigate(['/server', addedServer.id, 'project', projectId]); + }); } } } diff --git a/src/app/components/drawings-listeners/drawing-added/drawing-added.component.spec.ts b/src/app/components/drawings-listeners/drawing-added/drawing-added.component.spec.ts index 4be0fd99..a5069bed 100644 --- a/src/app/components/drawings-listeners/drawing-added/drawing-added.component.spec.ts +++ b/src/app/components/drawings-listeners/drawing-added/drawing-added.component.spec.ts @@ -1,18 +1,18 @@ -import { DrawingAddedComponent } from './drawing-added.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { DrawingService } from '../../../services/drawing.service'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; -import { MockedDrawingService, MockedDrawingsDataSource } from '../../project-map/project-map.component.spec'; -import { TextElementFactory } from '../../../cartography/helpers/drawings-factory/text-element-factory'; -import { EllipseElementFactory } from '../../../cartography/helpers/drawings-factory/ellipse-element-factory'; -import { RectangleElementFactory } from '../../../cartography/helpers/drawings-factory/rectangle-element-factory'; -import { LineElementFactory } from '../../../cartography/helpers/drawings-factory/line-element-factory'; -import { Project } from '../../../models/project'; import { AddedDataEvent } from '../../../cartography/events/event-source'; -import { Observable } from 'rxjs'; +import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; +import { EllipseElementFactory } from '../../../cartography/helpers/drawings-factory/ellipse-element-factory'; +import { LineElementFactory } from '../../../cartography/helpers/drawings-factory/line-element-factory'; +import { RectangleElementFactory } from '../../../cartography/helpers/drawings-factory/rectangle-element-factory'; +import { TextElementFactory } from '../../../cartography/helpers/drawings-factory/text-element-factory'; +import { Project } from '../../../models/project'; +import { DrawingService } from '../../../services/drawing.service'; +import { MockedDrawingsDataSource, MockedDrawingService } from '../../project-map/project-map.component.spec'; +import { DrawingAddedComponent } from './drawing-added.component'; describe('DrawingAddedComponent', () => { let component: DrawingAddedComponent; @@ -34,9 +34,9 @@ describe('DrawingAddedComponent', () => { { provide: DrawingsDataSource, useValue: mockedDrawingsDataSource }, { provide: DrawingsEventSource, useValue: mockedDrawingsEventSource }, { provide: DefaultDrawingsFactory, useValue: mockedDrawingsFactory }, - { provide: MapDrawingToSvgConverter, useClass: MapDrawingToSvgConverter } + { provide: MapDrawingToSvgConverter, useClass: MapDrawingToSvgConverter }, ], - declarations: [DrawingAddedComponent] + declarations: [DrawingAddedComponent], }).compileComponents(); })); diff --git a/src/app/components/drawings-listeners/drawing-added/drawing-added.component.ts b/src/app/components/drawings-listeners/drawing-added/drawing-added.component.ts index 3ab46f8c..f43c825f 100644 --- a/src/app/components/drawings-listeners/drawing-added/drawing-added.component.ts +++ b/src/app/components/drawings-listeners/drawing-added/drawing-added.component.ts @@ -1,19 +1,19 @@ -import { Component, OnInit, OnDestroy, Input, Output, EventEmitter, SimpleChange } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, SimpleChange } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; -import { Server } from '../../../models/server'; -import { Project } from '../../../models/project'; -import { Subscription } from 'rxjs'; -import { DrawingService } from '../../../services/drawing.service'; -import { Drawing } from '../../../cartography/models/drawing'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { AddedDataEvent } from '../../../cartography/events/event-source'; +import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; +import { Drawing } from '../../../cartography/models/drawing'; +import { Project } from '../../../models/project'; +import { Server } from '../../../models/server'; +import { DrawingService } from '../../../services/drawing.service'; @Component({ selector: 'app-drawing-added', templateUrl: './drawing-added.component.html', - styleUrls: ['./drawing-added.component.scss'] + styleUrls: ['./drawing-added.component.scss'], }) export class DrawingAddedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -31,7 +31,7 @@ export class DrawingAddedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.pointToAddSelected = this.drawingsEventSource.pointToAddSelected.subscribe(evt => this.onDrawingSaved(evt)); + this.pointToAddSelected = this.drawingsEventSource.pointToAddSelected.subscribe((evt) => this.onDrawingSaved(evt)); } ngOnChanges(changes: { [propKey: string]: SimpleChange }) { diff --git a/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.spec.ts b/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.spec.ts index cd6e6684..4f9e1edc 100644 --- a/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.spec.ts +++ b/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.spec.ts @@ -1,13 +1,13 @@ -import { DrawingDraggedComponent } from './drawing-dragged.component'; -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; -import { DrawingService } from '../../../services/drawing.service'; -import { MockedDrawingService, MockedDrawingsDataSource } from '../../project-map/project-map.component.spec'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawing } from '../../../cartography/models/map/map-drawing'; import { DraggedDataEvent } from '../../../cartography/events/event-source'; import { DrawingElement } from '../../../cartography/models/drawings/drawing-element'; -import { Observable } from 'rxjs'; +import { MapDrawing } from '../../../cartography/models/map/map-drawing'; +import { DrawingService } from '../../../services/drawing.service'; +import { MockedDrawingsDataSource, MockedDrawingService } from '../../project-map/project-map.component.spec'; +import { DrawingDraggedComponent } from './drawing-dragged.component'; describe('DrawingDraggedComponent', () => { let component: DrawingDraggedComponent; @@ -21,9 +21,9 @@ describe('DrawingDraggedComponent', () => { providers: [ { provide: DrawingService, useValue: mockedDrawingService }, { provide: DrawingsDataSource, useValue: mockedDrawingsDataSource }, - { provide: DrawingsEventSource, useValue: mockedDrawingsEventSource } + { provide: DrawingsEventSource, useValue: mockedDrawingsEventSource }, ], - declarations: [DrawingDraggedComponent] + declarations: [DrawingDraggedComponent], }).compileComponents(); })); @@ -44,7 +44,7 @@ describe('DrawingDraggedComponent', () => { it('should call drawing service when drawing is dragged', () => { const mapDrawingElement: DrawingElement = { width: 100, - height: 100 + height: 100, }; const mapDrawing: MapDrawing = { id: 'sampleId', @@ -55,7 +55,7 @@ describe('DrawingDraggedComponent', () => { x: 0, y: 0, z: 0, - element: mapDrawingElement + element: mapDrawingElement, }; const drawingDraggedDataEvent = new DraggedDataEvent(mapDrawing, 0, 0); spyOn(mockedDrawingService, 'updatePosition').and.returnValue(Observable.of()); diff --git a/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.ts b/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.ts index 85cf6de8..dc33b8fa 100644 --- a/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.ts +++ b/src/app/components/drawings-listeners/drawing-dragged/drawing-dragged.component.ts @@ -1,18 +1,18 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; +import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; +import { DraggedDataEvent } from '../../../cartography/events/event-source'; +import { Drawing } from '../../../cartography/models/drawing'; +import { MapDrawing } from '../../../cartography/models/map/map-drawing'; +import { Project } from '../../../models/project'; import { Server } from '../../../models/server'; import { DrawingService } from '../../../services/drawing.service'; -import { DraggedDataEvent } from '../../../cartography/events/event-source'; -import { MapDrawing } from '../../../cartography/models/map/map-drawing'; -import { Drawing } from '../../../cartography/models/drawing'; -import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { Project } from '../../../models/project'; @Component({ selector: 'app-drawing-dragged', templateUrl: './drawing-dragged.component.html', - styleUrls: ['./drawing-dragged.component.scss'] + styleUrls: ['./drawing-dragged.component.scss'], }) export class DrawingDraggedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -26,7 +26,7 @@ export class DrawingDraggedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.drawingDragged = this.drawingsEventSource.dragged.subscribe(evt => this.onDrawingDragged(evt)); + this.drawingDragged = this.drawingsEventSource.dragged.subscribe((evt) => this.onDrawingDragged(evt)); } onDrawingDragged(draggedEvent: DraggedDataEvent) { diff --git a/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.spec.ts b/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.spec.ts index 0af53fda..fa084cae 100644 --- a/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.spec.ts +++ b/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.spec.ts @@ -1,14 +1,14 @@ -import { DrawingResizedComponent } from './drawing-resized.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { DrawingService } from '../../../services/drawing.service'; -import { MockedDrawingService, MockedDrawingsDataSource } from '../../project-map/project-map.component.spec'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { ResizedDataEvent } from '../../../cartography/events/event-source'; -import { MapDrawing } from '../../../cartography/models/map/map-drawing'; import { DrawingElement } from '../../../cartography/models/drawings/drawing-element'; -import { Observable } from 'rxjs'; +import { MapDrawing } from '../../../cartography/models/map/map-drawing'; +import { DrawingService } from '../../../services/drawing.service'; +import { MockedDrawingsDataSource, MockedDrawingService } from '../../project-map/project-map.component.spec'; +import { DrawingResizedComponent } from './drawing-resized.component'; describe('DrawingResizedComponent', () => { let component: DrawingResizedComponent; @@ -24,9 +24,9 @@ describe('DrawingResizedComponent', () => { { provide: DrawingService, useValue: mockedDrawingService }, { provide: DrawingsDataSource, useValue: mockedDrawingsDataSource }, { provide: DrawingsEventSource, useValue: mockedDrawingsEventSource }, - { provide: MapDrawingToSvgConverter, useValue: mockedMapDrawingToSvgConverter } + { provide: MapDrawingToSvgConverter, useValue: mockedMapDrawingToSvgConverter }, ], - declarations: [DrawingResizedComponent] + declarations: [DrawingResizedComponent], }).compileComponents(); })); @@ -47,7 +47,7 @@ describe('DrawingResizedComponent', () => { it('should call drawing service when drawing is resized', () => { const mapDrawingElement: DrawingElement = { width: 100, - height: 100 + height: 100, }; const mapDrawing: MapDrawing = { id: 'sampleId', @@ -58,7 +58,7 @@ describe('DrawingResizedComponent', () => { x: 0, y: 0, z: 0, - element: mapDrawingElement + element: mapDrawingElement, }; const drawingResizedDataEvent = new ResizedDataEvent(mapDrawing, 0, 0, 100, 100); spyOn(mockedDrawingService, 'updateSizeAndPosition').and.returnValue(Observable.of()); diff --git a/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.ts b/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.ts index 1a374ffe..ef8fc203 100644 --- a/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.ts +++ b/src/app/components/drawings-listeners/drawing-resized/drawing-resized.component.ts @@ -1,18 +1,18 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; -import { DrawingService } from '../../../services/drawing.service'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; -import { Server } from '../../../models/server'; import { ResizedDataEvent } from '../../../cartography/events/event-source'; -import { MapDrawing } from '../../../cartography/models/map/map-drawing'; import { Drawing } from '../../../cartography/models/drawing'; -import { Subscription } from 'rxjs'; +import { MapDrawing } from '../../../cartography/models/map/map-drawing'; +import { Server } from '../../../models/server'; +import { DrawingService } from '../../../services/drawing.service'; @Component({ selector: 'app-drawing-resized', templateUrl: './drawing-resized.component.html', - styleUrls: ['./drawing-resized.component.scss'] + styleUrls: ['./drawing-resized.component.scss'], }) export class DrawingResizedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -26,7 +26,7 @@ export class DrawingResizedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.drawingResized = this.drawingsEventSource.resized.subscribe(evt => this.onDrawingResized(evt)); + this.drawingResized = this.drawingsEventSource.resized.subscribe((evt) => this.onDrawingResized(evt)); } onDrawingResized(resizedEvent: ResizedDataEvent) { diff --git a/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.spec.ts b/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.spec.ts index 9a727c13..54cc07ff 100644 --- a/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.spec.ts +++ b/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.spec.ts @@ -1,15 +1,15 @@ -import { InterfaceLabelDraggedComponent } from './interface-label-dragged.component'; -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; -import { MockedLinkService } from '../../project-map/project-map.component.spec'; -import { LinksEventSource } from '../../../cartography/events/links-event-source'; -import { LinkService } from '../../../services/link.service'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; import { LinksDataSource } from '../../../cartography/datasources/links-datasource'; import { DraggedDataEvent } from '../../../cartography/events/event-source'; -import { MapLinkNode } from '../../../cartography/models/map/map-link-node'; -import { Observable } from 'rxjs'; -import { MapLabel } from '../../../cartography/models/map/map-label'; -import { Link } from '../../../models/link'; +import { LinksEventSource } from '../../../cartography/events/links-event-source'; import { Label } from '../../../cartography/models/label'; +import { MapLabel } from '../../../cartography/models/map/map-label'; +import { MapLinkNode } from '../../../cartography/models/map/map-link-node'; +import { Link } from '../../../models/link'; +import { LinkService } from '../../../services/link.service'; +import { MockedLinkService } from '../../project-map/project-map.component.spec'; +import { InterfaceLabelDraggedComponent } from './interface-label-dragged.component'; describe('InterfaceLabelDraggedComponent', () => { let component: InterfaceLabelDraggedComponent; @@ -23,9 +23,9 @@ describe('InterfaceLabelDraggedComponent', () => { providers: [ { provide: LinkService, useValue: mockedLinkService }, { provide: LinksDataSource, useValue: mockedLinksDataSource }, - { provide: LinksEventSource, useValue: mockedLinksEventSource } + { provide: LinksEventSource, useValue: mockedLinksEventSource }, ], - declarations: [InterfaceLabelDraggedComponent] + declarations: [InterfaceLabelDraggedComponent], }).compileComponents(); })); @@ -50,7 +50,7 @@ describe('InterfaceLabelDraggedComponent', () => { linkId: 'sampleLinkId', adapterNumber: 0, portNumber: 0, - label: {} as MapLabel + label: {} as MapLabel, }; const interfaceLabelDraggedDataEvent = new DraggedDataEvent(mapLinkNode, 0, 0); @@ -60,14 +60,14 @@ describe('InterfaceLabelDraggedComponent', () => { node_id: '1', adapter_number: 0, port_number: 0, - label: {} as Label + label: {} as Label, }, { node_id: '2', adapter_number: 0, port_number: 0, - label: {} as Label - } + label: {} as Label, + }, ]; mockedLinksDataSource = TestBed.get(LinksDataSource); diff --git a/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.ts b/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.ts index 4575c53e..124674ea 100644 --- a/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.ts +++ b/src/app/components/drawings-listeners/interface-label-dragged/interface-label-dragged.component.ts @@ -1,17 +1,17 @@ import { Component, Input } from '@angular/core'; -import { Server } from '../../../models/server'; +import { Subscription } from 'rxjs'; import { LinksDataSource } from '../../../cartography/datasources/links-datasource'; -import { LinkService } from '../../../services/link.service'; import { DraggedDataEvent } from '../../../cartography/events/event-source'; +import { LinksEventSource } from '../../../cartography/events/links-event-source'; import { MapLinkNode } from '../../../cartography/models/map/map-link-node'; import { Link } from '../../../models/link'; -import { Subscription } from 'rxjs'; -import { LinksEventSource } from '../../../cartography/events/links-event-source'; +import { Server } from '../../../models/server'; +import { LinkService } from '../../../services/link.service'; @Component({ selector: 'app-interface-label-dragged', templateUrl: './interface-label-dragged.component.html', - styleUrls: ['./interface-label-dragged.component.scss'] + styleUrls: ['./interface-label-dragged.component.scss'], }) export class InterfaceLabelDraggedComponent { @Input() server: Server; @@ -24,7 +24,9 @@ export class InterfaceLabelDraggedComponent { ) {} ngOnInit() { - this.interfaceDragged = this.linksEventSource.interfaceDragged.subscribe(evt => this.onInterfaceLabelDragged(evt)); + this.interfaceDragged = this.linksEventSource.interfaceDragged.subscribe((evt) => + this.onInterfaceLabelDragged(evt) + ); } onInterfaceLabelDragged(draggedEvent: DraggedDataEvent) { diff --git a/src/app/components/drawings-listeners/link-created/link-created.component.spec.ts b/src/app/components/drawings-listeners/link-created/link-created.component.spec.ts index 06547cb8..ba97514b 100644 --- a/src/app/components/drawings-listeners/link-created/link-created.component.spec.ts +++ b/src/app/components/drawings-listeners/link-created/link-created.component.spec.ts @@ -1,23 +1,23 @@ -import { LinkCreatedComponent } from './link-created.component'; -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; -import { ProjectService } from '../../../services/project.service'; -import { MockedProjectService } from '../../../services/project.service.spec'; -import { LinkService } from '../../../services/link.service'; -import { LinksDataSource } from '../../../cartography/datasources/links-datasource'; -import { LinksEventSource } from '../../../cartography/events/links-event-source'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; +import { MapLabelToLabelConverter } from '../../../cartography/converters/map/map-label-to-label-converter'; import { MapNodeToNodeConverter } from '../../../cartography/converters/map/map-node-to-node-converter'; import { MapPortToPortConverter } from '../../../cartography/converters/map/map-port-to-port-converter'; -import { MockedLinkService } from '../../project-map/project-map.component.spec'; -import { MapLabelToLabelConverter } from '../../../cartography/converters/map/map-label-to-label-converter'; -import { FontBBoxCalculator } from '../../../cartography/helpers/font-bbox-calculator'; -import { CssFixer } from '../../../cartography/helpers/css-fixer'; -import { FontFixer } from '../../../cartography/helpers/font-fixer'; +import { LinksDataSource } from '../../../cartography/datasources/links-datasource'; import { MapLinkCreated } from '../../../cartography/events/links'; -import { MapNode } from '../../../cartography/models/map/map-node'; +import { LinksEventSource } from '../../../cartography/events/links-event-source'; +import { CssFixer } from '../../../cartography/helpers/css-fixer'; +import { FontBBoxCalculator } from '../../../cartography/helpers/font-bbox-calculator'; +import { FontFixer } from '../../../cartography/helpers/font-fixer'; import { MapLabel } from '../../../cartography/models/map/map-label'; +import { MapNode } from '../../../cartography/models/map/map-node'; import { MapPort } from '../../../cartography/models/map/map-port'; -import { Observable } from 'rxjs'; import { Project } from '../../../models/project'; +import { LinkService } from '../../../services/link.service'; +import { ProjectService } from '../../../services/project.service'; +import { MockedProjectService } from '../../../services/project.service.spec'; +import { MockedLinkService } from '../../project-map/project-map.component.spec'; +import { LinkCreatedComponent } from './link-created.component'; describe('LinkCreatedComponent', () => { let component: LinkCreatedComponent; @@ -38,9 +38,9 @@ describe('LinkCreatedComponent', () => { { provide: LinksDataSource, useClass: LinksDataSource }, { provide: LinksEventSource, useValue: mockedLinksEventSource }, { provide: MapNodeToNodeConverter, useValue: mockedMapNodeToNodeConverter }, - { provide: MapPortToPortConverter, useClass: MapPortToPortConverter } + { provide: MapPortToPortConverter, useClass: MapPortToPortConverter }, ], - declarations: [LinkCreatedComponent] + declarations: [LinkCreatedComponent], }).compileComponents(); })); @@ -86,14 +86,14 @@ describe('LinkCreatedComponent', () => { width: 0, x: 0, y: 0, - z: 0 + z: 0, }; const mapPort: MapPort = { adapterNumber: 1, linkType: 'sampleLinkType', name: 'sampleName', portNumber: 1, - shortName: 'sampleShortName' + shortName: 'sampleShortName', }; const linkCreatedDataEvent = new MapLinkCreated(mapNode, mapPort, mapNode, mapPort); spyOn(mockedLinkService, 'createLink').and.returnValue(Observable.of({})); diff --git a/src/app/components/drawings-listeners/link-created/link-created.component.ts b/src/app/components/drawings-listeners/link-created/link-created.component.ts index 442c73e6..f115ca90 100644 --- a/src/app/components/drawings-listeners/link-created/link-created.component.ts +++ b/src/app/components/drawings-listeners/link-created/link-created.component.ts @@ -1,20 +1,20 @@ -import { Component, OnDestroy, Input, OnInit } from '@angular/core'; -import { Server } from '../../../models/server'; -import { LinkService } from '../../../services/link.service'; -import { ProjectService } from '../../../services/project.service'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; import { MapNodeToNodeConverter } from '../../../cartography/converters/map/map-node-to-node-converter'; import { MapPortToPortConverter } from '../../../cartography/converters/map/map-port-to-port-converter'; import { LinksDataSource } from '../../../cartography/datasources/links-datasource'; -import { Subscription } from 'rxjs'; -import { Project } from '../../../models/project'; import { MapLinkCreated } from '../../../cartography/events/links'; -import { Link } from '../../../models/link'; import { LinksEventSource } from '../../../cartography/events/links-event-source'; +import { Link } from '../../../models/link'; +import { Project } from '../../../models/project'; +import { Server } from '../../../models/server'; +import { LinkService } from '../../../services/link.service'; +import { ProjectService } from '../../../services/project.service'; @Component({ selector: 'app-link-created', templateUrl: './link-created.component.html', - styleUrls: ['./link-created.component.scss'] + styleUrls: ['./link-created.component.scss'], }) export class LinkCreatedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -31,7 +31,7 @@ export class LinkCreatedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.linkCreated = this.linksEventSource.created.subscribe(evt => this.onLinkCreated(evt)); + this.linkCreated = this.linksEventSource.created.subscribe((evt) => this.onLinkCreated(evt)); } onLinkCreated(linkCreated: MapLinkCreated) { @@ -39,7 +39,7 @@ export class LinkCreatedComponent implements OnInit, OnDestroy { const yLength = Math.abs(linkCreated.sourceNode.y - linkCreated.targetNode.y); const zLength = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2)); //from law of sines - const sinY = yLength/zLength; + const sinY = yLength / zLength; const x = (45 / zLength) * xLength; const y = (45 / zLength) * yLength; @@ -49,26 +49,35 @@ export class LinkCreatedComponent implements OnInit, OnDestroy { let xLabelTargetNode = 0; let yLabelTargetNode = 0; - if ((linkCreated.sourceNode.x <= linkCreated.targetNode.x) && (linkCreated.sourceNode.y <= linkCreated.targetNode.y)) { - xLabelSourceNode = Math.floor(linkCreated.sourceNode.width/2) + Math.round(x) + 5; - yLabelSourceNode = Math.floor(linkCreated.sourceNode.height/2) + Math.round(y) + 5; - xLabelTargetNode = Math.floor(linkCreated.targetNode.width/2) - Math.round(x) - 5 - Math.round(20 * sinY); - yLabelTargetNode = Math.floor(linkCreated.targetNode.height/2) - Math.round(y) + 5 - Math.round(20 * sinY); - } else if ((linkCreated.sourceNode.x > linkCreated.targetNode.x) && (linkCreated.sourceNode.y < linkCreated.targetNode.y)) { - xLabelSourceNode = Math.floor(linkCreated.sourceNode.width/2) - Math.round(x) - 5 - Math.round(20 * sinY); - yLabelSourceNode = Math.floor(linkCreated.sourceNode.height/2) + Math.round(y) + 5 - Math.round(20 * sinY); - xLabelTargetNode = Math.floor(linkCreated.targetNode.width/2) + Math.round(x) + 5; - yLabelTargetNode = Math.floor(linkCreated.targetNode.height/2) - Math.round(y) - 5; - } else if ((linkCreated.sourceNode.x < linkCreated.targetNode.x) && (linkCreated.sourceNode.y > linkCreated.targetNode.y)) { - xLabelSourceNode = Math.floor(linkCreated.sourceNode.width/2) + Math.round(x) + 5 - Math.round(20 * sinY); - yLabelSourceNode = Math.floor(linkCreated.sourceNode.height/2) - Math.round(y) - 5 - Math.round(20 * sinY); - xLabelTargetNode = Math.floor(linkCreated.targetNode.width/2) - Math.round(x) - 5; - yLabelTargetNode = Math.floor(linkCreated.targetNode.height/2) + Math.round(y) + 5; - } else if ((linkCreated.sourceNode.x >= linkCreated.targetNode.x) && (linkCreated.sourceNode.y >= linkCreated.targetNode.y)) { - xLabelSourceNode = Math.floor(linkCreated.sourceNode.width/2) - Math.round(x) - 5 - Math.round(20 * sinY); - yLabelSourceNode = Math.floor(linkCreated.sourceNode.height/2) - Math.round(y) + 5 - Math.round(20 * sinY); - xLabelTargetNode = Math.floor(linkCreated.targetNode.width/2) + Math.round(x) + 5; - yLabelTargetNode = Math.floor(linkCreated.targetNode.height/2) + Math.round(y) + 5; + if (linkCreated.sourceNode.x <= linkCreated.targetNode.x && linkCreated.sourceNode.y <= linkCreated.targetNode.y) { + xLabelSourceNode = Math.floor(linkCreated.sourceNode.width / 2) + Math.round(x) + 5; + yLabelSourceNode = Math.floor(linkCreated.sourceNode.height / 2) + Math.round(y) + 5; + xLabelTargetNode = Math.floor(linkCreated.targetNode.width / 2) - Math.round(x) - 5 - Math.round(20 * sinY); + yLabelTargetNode = Math.floor(linkCreated.targetNode.height / 2) - Math.round(y) + 5 - Math.round(20 * sinY); + } else if ( + linkCreated.sourceNode.x > linkCreated.targetNode.x && + linkCreated.sourceNode.y < linkCreated.targetNode.y + ) { + xLabelSourceNode = Math.floor(linkCreated.sourceNode.width / 2) - Math.round(x) - 5 - Math.round(20 * sinY); + yLabelSourceNode = Math.floor(linkCreated.sourceNode.height / 2) + Math.round(y) + 5 - Math.round(20 * sinY); + xLabelTargetNode = Math.floor(linkCreated.targetNode.width / 2) + Math.round(x) + 5; + yLabelTargetNode = Math.floor(linkCreated.targetNode.height / 2) - Math.round(y) - 5; + } else if ( + linkCreated.sourceNode.x < linkCreated.targetNode.x && + linkCreated.sourceNode.y > linkCreated.targetNode.y + ) { + xLabelSourceNode = Math.floor(linkCreated.sourceNode.width / 2) + Math.round(x) + 5 - Math.round(20 * sinY); + yLabelSourceNode = Math.floor(linkCreated.sourceNode.height / 2) - Math.round(y) - 5 - Math.round(20 * sinY); + xLabelTargetNode = Math.floor(linkCreated.targetNode.width / 2) - Math.round(x) - 5; + yLabelTargetNode = Math.floor(linkCreated.targetNode.height / 2) + Math.round(y) + 5; + } else if ( + linkCreated.sourceNode.x >= linkCreated.targetNode.x && + linkCreated.sourceNode.y >= linkCreated.targetNode.y + ) { + xLabelSourceNode = Math.floor(linkCreated.sourceNode.width / 2) - Math.round(x) - 5 - Math.round(20 * sinY); + yLabelSourceNode = Math.floor(linkCreated.sourceNode.height / 2) - Math.round(y) + 5 - Math.round(20 * sinY); + xLabelTargetNode = Math.floor(linkCreated.targetNode.width / 2) + Math.round(x) + 5; + yLabelTargetNode = Math.floor(linkCreated.targetNode.height / 2) + Math.round(y) + 5; } const sourceNode = this.mapNodeToNode.convert(linkCreated.sourceNode); @@ -76,11 +85,23 @@ export class LinkCreatedComponent implements OnInit, OnDestroy { const targetNode = this.mapNodeToNode.convert(linkCreated.targetNode); const targetPort = this.mapPortToPort.convert(linkCreated.targetPort); - this.linkService.createLink(this.server, sourceNode, sourcePort, targetNode, targetPort, xLabelSourceNode, yLabelSourceNode, xLabelTargetNode, yLabelTargetNode).subscribe(() => { - this.projectService.links(this.server, this.project.project_id).subscribe((links: Link[]) => { - this.linksDataSource.set(links); + this.linkService + .createLink( + this.server, + sourceNode, + sourcePort, + targetNode, + targetPort, + xLabelSourceNode, + yLabelSourceNode, + xLabelTargetNode, + yLabelTargetNode + ) + .subscribe(() => { + this.projectService.links(this.server, this.project.project_id).subscribe((links: Link[]) => { + this.linksDataSource.set(links); + }); }); - }); } ngOnDestroy() { diff --git a/src/app/components/drawings-listeners/node-dragged/node-dragged.component.spec.ts b/src/app/components/drawings-listeners/node-dragged/node-dragged.component.spec.ts index 82b67ff5..0b69c34f 100644 --- a/src/app/components/drawings-listeners/node-dragged/node-dragged.component.spec.ts +++ b/src/app/components/drawings-listeners/node-dragged/node-dragged.component.spec.ts @@ -1,13 +1,13 @@ -import { NodeDraggedComponent } from './node-dragged.component'; -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; -import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; -import { NodeService } from '../../../services/node.service'; -import { NodesEventSource } from '../../../cartography/events/nodes-event-source'; -import { MockedNodeService, MockedNodesDataSource } from '../../project-map/project-map.component.spec'; -import { DraggedDataEvent } from '../../../cartography/events/event-source'; -import { MapNode } from '../../../cartography/models/map/map-node'; -import { MapLabel } from '../../../cartography/models/map/map-label'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { Observable } from 'rxjs'; +import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; +import { DraggedDataEvent } from '../../../cartography/events/event-source'; +import { NodesEventSource } from '../../../cartography/events/nodes-event-source'; +import { MapLabel } from '../../../cartography/models/map/map-label'; +import { MapNode } from '../../../cartography/models/map/map-node'; +import { NodeService } from '../../../services/node.service'; +import { MockedNodesDataSource, MockedNodeService } from '../../project-map/project-map.component.spec'; +import { NodeDraggedComponent } from './node-dragged.component'; describe('NodeDraggedComponent', () => { let component: NodeDraggedComponent; @@ -21,9 +21,9 @@ describe('NodeDraggedComponent', () => { providers: [ { provide: NodesDataSource, useValue: mockedNodesDataSource }, { provide: NodeService, useValue: mockedNodeService }, - { provide: NodesEventSource, useValue: mockedNodesEventSource } + { provide: NodesEventSource, useValue: mockedNodesEventSource }, ], - declarations: [NodeDraggedComponent] + declarations: [NodeDraggedComponent], }).compileComponents(); })); @@ -66,7 +66,7 @@ describe('NodeDraggedComponent', () => { width: 0, x: 0, y: 0, - z: 0 + z: 0, }; const draggedDataEvent = new DraggedDataEvent(mapNode, 0, 0); spyOn(mockedNodeService, 'updatePosition').and.returnValue(Observable.of()); diff --git a/src/app/components/drawings-listeners/node-dragged/node-dragged.component.ts b/src/app/components/drawings-listeners/node-dragged/node-dragged.component.ts index bb97c2b9..7730d4b2 100644 --- a/src/app/components/drawings-listeners/node-dragged/node-dragged.component.ts +++ b/src/app/components/drawings-listeners/node-dragged/node-dragged.component.ts @@ -1,22 +1,22 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; -import { NodeService } from '../../../services/node.service'; import { DraggedDataEvent } from '../../../cartography/events/event-source'; -import { Node } from '../../../cartography/models/node'; -import { Server } from '../../../models/server'; import { NodesEventSource } from '../../../cartography/events/nodes-event-source'; import { MapNode } from '../../../cartography/models/map/map-node'; -import { Subscription } from 'rxjs'; +import { Node } from '../../../cartography/models/node'; import { Project } from '../../../models/project'; +import { Server } from '../../../models/server'; +import { NodeService } from '../../../services/node.service'; @Component({ selector: 'app-node-dragged', templateUrl: './node-dragged.component.html', - styleUrls: ['./node-dragged.component.scss'] + styleUrls: ['./node-dragged.component.scss'], }) export class NodeDraggedComponent implements OnInit, OnDestroy { @Input() server: Server; - @Input() project: Project + @Input() project: Project; private nodeDragged: Subscription; constructor( @@ -26,7 +26,7 @@ export class NodeDraggedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.nodeDragged = this.nodesEventSource.dragged.subscribe(evt => this.onNodeDragged(evt)); + this.nodeDragged = this.nodesEventSource.dragged.subscribe((evt) => this.onNodeDragged(evt)); } onNodeDragged(draggedEvent: DraggedDataEvent) { diff --git a/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.spec.ts b/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.spec.ts index 08751c03..2767728c 100644 --- a/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.spec.ts +++ b/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.spec.ts @@ -1,16 +1,16 @@ -import { NodeLabelDraggedComponent } from './node-label-dragged.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; -import { NodeService } from '../../../services/node.service'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; import { MapLabelToLabelConverter } from '../../../cartography/converters/map/map-label-to-label-converter'; +import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; +import { DraggedDataEvent } from '../../../cartography/events/event-source'; import { NodesEventSource } from '../../../cartography/events/nodes-event-source'; import { CssFixer } from '../../../cartography/helpers/css-fixer'; -import { FontFixer } from '../../../cartography/helpers/font-fixer'; import { FontBBoxCalculator } from '../../../cartography/helpers/font-bbox-calculator'; -import { MockedNodeService, MockedNodesDataSource } from '../../project-map/project-map.component.spec'; -import { DraggedDataEvent } from '../../../cartography/events/event-source'; +import { FontFixer } from '../../../cartography/helpers/font-fixer'; import { MapLabel } from '../../../cartography/models/map/map-label'; -import { Observable } from 'rxjs'; +import { NodeService } from '../../../services/node.service'; +import { MockedNodesDataSource, MockedNodeService } from '../../project-map/project-map.component.spec'; +import { NodeLabelDraggedComponent } from './node-label-dragged.component'; describe('NodeLabelDraggedComponent', () => { let component: NodeLabelDraggedComponent; @@ -30,9 +30,9 @@ describe('NodeLabelDraggedComponent', () => { { provide: NodesDataSource, useValue: mockedNodesDataSource }, { provide: NodeService, useValue: mockedNodeService }, { provide: NodesEventSource, useValue: mockedNodesEventSource }, - { provide: MapLabelToLabelConverter, useValue: mapLabelToLabelConverter } + { provide: MapLabelToLabelConverter, useValue: mapLabelToLabelConverter }, ], - declarations: [NodeLabelDraggedComponent] + declarations: [NodeLabelDraggedComponent], }).compileComponents(); })); @@ -60,7 +60,7 @@ describe('NodeLabelDraggedComponent', () => { y: 0, originalX: 0, originalY: 0, - nodeId: 'node id' + nodeId: 'node id', }; const nodeDraggedDataEvent = new DraggedDataEvent(mapLabel, 0, 0); spyOn(mockedNodeService, 'updateLabel').and.returnValue(Observable.of()); diff --git a/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.ts b/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.ts index d3b7ffa3..9a3bcc47 100644 --- a/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.ts +++ b/src/app/components/drawings-listeners/node-label-dragged/node-label-dragged.component.ts @@ -1,18 +1,18 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; -import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; -import { NodesEventSource } from '../../../cartography/events/nodes-event-source'; -import { NodeService } from '../../../services/node.service'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; import { MapLabelToLabelConverter } from '../../../cartography/converters/map/map-label-to-label-converter'; +import { NodesDataSource } from '../../../cartography/datasources/nodes-datasource'; +import { DraggedDataEvent } from '../../../cartography/events/event-source'; +import { NodesEventSource } from '../../../cartography/events/nodes-event-source'; +import { MapLabel } from '../../../cartography/models/map/map-label'; import { Node } from '../../../cartography/models/node'; import { Server } from '../../../models/server'; -import { Subscription } from 'rxjs'; -import { DraggedDataEvent } from '../../../cartography/events/event-source'; -import { MapLabel } from '../../../cartography/models/map/map-label'; +import { NodeService } from '../../../services/node.service'; @Component({ selector: 'app-node-label-dragged', templateUrl: './node-label-dragged.component.html', - styleUrls: ['./node-label-dragged.component.scss'] + styleUrls: ['./node-label-dragged.component.scss'], }) export class NodeLabelDraggedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -26,7 +26,7 @@ export class NodeLabelDraggedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.nodeLabelDragged = this.nodesEventSource.labelDragged.subscribe(evt => this.onNodeLabelDragged(evt)); + this.nodeLabelDragged = this.nodesEventSource.labelDragged.subscribe((evt) => this.onNodeLabelDragged(evt)); } onNodeLabelDragged(draggedEvent: DraggedDataEvent) { diff --git a/src/app/components/drawings-listeners/text-added/text-added.component.spec.ts b/src/app/components/drawings-listeners/text-added/text-added.component.spec.ts index 8eab7805..8f9f32d3 100644 --- a/src/app/components/drawings-listeners/text-added/text-added.component.spec.ts +++ b/src/app/components/drawings-listeners/text-added/text-added.component.spec.ts @@ -1,19 +1,19 @@ -import { TextAddedComponent } from './text-added.component'; -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; -import { DrawingService } from '../../../services/drawing.service'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; -import { MockedDrawingService, MockedDrawingsDataSource } from '../../project-map/project-map.component.spec'; -import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; -import { Context } from '../../../cartography/models/context'; import { TextAddedDataEvent } from '../../../cartography/events/event-source'; -import { Observable } from 'rxjs'; -import { TextElementFactory } from '../../../cartography/helpers/drawings-factory/text-element-factory'; +import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; import { EllipseElementFactory } from '../../../cartography/helpers/drawings-factory/ellipse-element-factory'; -import { RectangleElementFactory } from '../../../cartography/helpers/drawings-factory/rectangle-element-factory'; import { LineElementFactory } from '../../../cartography/helpers/drawings-factory/line-element-factory'; +import { RectangleElementFactory } from '../../../cartography/helpers/drawings-factory/rectangle-element-factory'; +import { TextElementFactory } from '../../../cartography/helpers/drawings-factory/text-element-factory'; +import { Context } from '../../../cartography/models/context'; import { Project } from '../../../models/project'; +import { DrawingService } from '../../../services/drawing.service'; +import { MockedDrawingsDataSource, MockedDrawingService } from '../../project-map/project-map.component.spec'; +import { TextAddedComponent } from './text-added.component'; describe('TextAddedComponent', () => { let component: TextAddedComponent; @@ -36,9 +36,9 @@ describe('TextAddedComponent', () => { { provide: DrawingsEventSource, useValue: mockedDrawingsEventSource }, { provide: DefaultDrawingsFactory, useValue: mockedDrawingsFactory }, { provide: MapDrawingToSvgConverter, useClass: MapDrawingToSvgConverter }, - { provide: Context, useClass: Context } + { provide: Context, useClass: Context }, ], - declarations: [TextAddedComponent] + declarations: [TextAddedComponent], }).compileComponents(); })); diff --git a/src/app/components/drawings-listeners/text-added/text-added.component.ts b/src/app/components/drawings-listeners/text-added/text-added.component.ts index 2071c4f1..d14311ee 100644 --- a/src/app/components/drawings-listeners/text-added/text-added.component.ts +++ b/src/app/components/drawings-listeners/text-added/text-added.component.ts @@ -1,21 +1,21 @@ -import { Component, OnInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subscription } from 'rxjs'; -import { DrawingService } from '../../../services/drawing.service'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { TextAddedDataEvent } from '../../../cartography/events/event-source'; import { DefaultDrawingsFactory } from '../../../cartography/helpers/default-drawings-factory'; -import { TextElement } from '../../../cartography/models/drawings/text-element'; -import { Server } from '../../../models/server'; -import { Project } from '../../../models/project'; -import { Drawing } from '../../../cartography/models/drawing'; import { Context } from '../../../cartography/models/context'; +import { Drawing } from '../../../cartography/models/drawing'; +import { TextElement } from '../../../cartography/models/drawings/text-element'; +import { Project } from '../../../models/project'; +import { Server } from '../../../models/server'; +import { DrawingService } from '../../../services/drawing.service'; @Component({ selector: 'app-text-added', templateUrl: './text-added.component.html', - styleUrls: ['./text-added.component.scss'] + styleUrls: ['./text-added.component.scss'], }) export class TextAddedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -33,7 +33,7 @@ export class TextAddedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.textAdded = this.drawingsEventSource.textAdded.subscribe(evt => this.onTextAdded(evt)); + this.textAdded = this.drawingsEventSource.textAdded.subscribe((evt) => this.onTextAdded(evt)); } onTextAdded(evt: TextAddedDataEvent) { @@ -45,8 +45,10 @@ export class TextAddedComponent implements OnInit, OnDestroy { .add( this.server, this.project.project_id, - (evt.x - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x))/this.context.transformation.k, - (evt.y - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y))/this.context.transformation.k, + (evt.x - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)) / + this.context.transformation.k, + (evt.y - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)) / + this.context.transformation.k, svgText ) .subscribe((serverDrawing: Drawing) => { diff --git a/src/app/components/drawings-listeners/text-edited/text-edited.component.spec.ts b/src/app/components/drawings-listeners/text-edited/text-edited.component.spec.ts index aae1cd55..ed0fae2d 100644 --- a/src/app/components/drawings-listeners/text-edited/text-edited.component.spec.ts +++ b/src/app/components/drawings-listeners/text-edited/text-edited.component.spec.ts @@ -1,13 +1,13 @@ -import { TextEditedComponent } from './text-edited.component'; -import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { DrawingService } from '../../../services/drawing.service'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable } from 'rxjs'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; -import { Observable } from 'rxjs'; import { TextEditedDataEvent } from '../../../cartography/events/event-source'; import { TextElement } from '../../../cartography/models/drawings/text-element'; -import { MockedDrawingService, MockedDrawingsDataSource } from '../../project-map/project-map.component.spec'; +import { DrawingService } from '../../../services/drawing.service'; +import { MockedDrawingsDataSource, MockedDrawingService } from '../../project-map/project-map.component.spec'; +import { TextEditedComponent } from './text-edited.component'; describe('TextEditedComponent', () => { let component: TextEditedComponent; @@ -22,9 +22,9 @@ describe('TextEditedComponent', () => { { provide: DrawingService, useValue: mockedDrawingService }, { provide: DrawingsDataSource, useValue: mockedDrawingsDataSource }, { provide: DrawingsEventSource, useValue: mockedDrawingsEventSource }, - { provide: MapDrawingToSvgConverter, useClass: MapDrawingToSvgConverter } + { provide: MapDrawingToSvgConverter, useClass: MapDrawingToSvgConverter }, ], - declarations: [TextEditedComponent] + declarations: [TextEditedComponent], }).compileComponents(); })); @@ -52,7 +52,7 @@ describe('TextEditedComponent', () => { font_family: 'font', font_size: 100, font_weight: 'bold', - text_decoration: 'sample decoration' + text_decoration: 'sample decoration', }; const textEditedDataEvent = new TextEditedDataEvent('id', 'edited text', textElement); spyOn(mockedDrawingService, 'updateText').and.returnValue(Observable.of()); diff --git a/src/app/components/drawings-listeners/text-edited/text-edited.component.ts b/src/app/components/drawings-listeners/text-edited/text-edited.component.ts index 438306d8..d5d5eaec 100644 --- a/src/app/components/drawings-listeners/text-edited/text-edited.component.ts +++ b/src/app/components/drawings-listeners/text-edited/text-edited.component.ts @@ -1,19 +1,19 @@ -import { Component, OnInit, OnDestroy, Input } from '@angular/core'; -import { TextEditedDataEvent } from '../../../cartography/events/event-source'; -import { MapDrawing } from '../../../cartography/models/map/map-drawing'; -import { TextElement } from '../../../cartography/models/drawings/text-element'; -import { Drawing } from '../../../cartography/models/drawing'; -import { Server } from '../../../models/server'; +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; -import { DrawingService } from '../../../services/drawing.service'; +import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; import { DrawingsDataSource } from '../../../cartography/datasources/drawings-datasource'; import { DrawingsEventSource } from '../../../cartography/events/drawings-event-source'; -import { MapDrawingToSvgConverter } from '../../../cartography/converters/map/map-drawing-to-svg-converter'; +import { TextEditedDataEvent } from '../../../cartography/events/event-source'; +import { Drawing } from '../../../cartography/models/drawing'; +import { TextElement } from '../../../cartography/models/drawings/text-element'; +import { MapDrawing } from '../../../cartography/models/map/map-drawing'; +import { Server } from '../../../models/server'; +import { DrawingService } from '../../../services/drawing.service'; @Component({ selector: 'app-text-edited', templateUrl: './text-edited.component.html', - styleUrls: ['./text-edited.component.scss'] + styleUrls: ['./text-edited.component.scss'], }) export class TextEditedComponent implements OnInit, OnDestroy { @Input() server: Server; @@ -27,7 +27,7 @@ export class TextEditedComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.textEdited = this.drawingsEventSource.textEdited.subscribe(evt => this.onTextEdited(evt)); + this.textEdited = this.drawingsEventSource.textEdited.subscribe((evt) => this.onTextEdited(evt)); } onTextEdited(evt: TextEditedDataEvent) { diff --git a/src/app/components/help/help.component.html b/src/app/components/help/help.component.html index 6f923b2b..124fe11e 100644 --- a/src/app/components/help/help.component.html +++ b/src/app/components/help/help.component.html @@ -1,35 +1,39 @@
-

Help

-
-
- - - - Useful shortcuts - - - ctrl + + to zoom in - ctrl + - to zoom out - ctrl + 0 to reset zoom - ctrl + h to hide toolbar - ctrl + a to select all items on map - ctrl + shift + a to deselect all items on map - ctrl + shift + s to go to preferences - - - - - Third party components - -
-
- - - Release notes - -
-
-
-
+

Help

+
+
+ + + + Useful shortcuts + + + ctrl + + to zoom in + ctrl + - to zoom out + ctrl + 0 to reset zoom + ctrl + h to hide toolbar + ctrl + a to select all items on map + ctrl + shift + a to deselect all items on map + ctrl + shift + s to go to preferences + + + + + Third party components + +
+
+ + + Release notes + +
+
+
+ + +
diff --git a/src/app/components/help/help.component.scss b/src/app/components/help/help.component.scss index e69de29b..d6a023a9 100644 --- a/src/app/components/help/help.component.scss +++ b/src/app/components/help/help.component.scss @@ -0,0 +1,4 @@ +.full-width { + width: 50%; + margin-top: 20px; +} diff --git a/src/app/components/help/help.component.ts b/src/app/components/help/help.component.ts index 512a9d21..032c5793 100644 --- a/src/app/components/help/help.component.ts +++ b/src/app/components/help/help.component.ts @@ -1,33 +1,31 @@ -import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; +import { Component, OnInit } from '@angular/core'; @Component({ -selector: 'app-help', -templateUrl: './help.component.html', -styleUrls: ['./help.component.scss'] + selector: 'app-help', + templateUrl: './help.component.html', + styleUrls: ['./help.component.scss'], }) export class HelpComponent implements OnInit { - thirdpartylicenses = ''; - releasenotes = ''; + thirdpartylicenses = ''; + releasenotes = ''; - constructor( - private httpClient: HttpClient - ) {} + constructor(private httpClient: HttpClient) {} - ngOnInit() { - this.httpClient.get(window.location.href + '/3rdpartylicenses.txt', {responseType: 'text'}) - .subscribe(data => { - this.thirdpartylicenses = data.replace(new RegExp('\n', 'g'), "
") - }, - error => { - if (error.status === 404) { - this.thirdpartylicenses = 'File not found'; - } - }); + ngOnInit() { + this.httpClient.get(window.location.href + '/3rdpartylicenses.txt', { responseType: 'text' }).subscribe( + (data) => { + this.thirdpartylicenses = data.replace(new RegExp('\n', 'g'), '
'); + }, + (error) => { + if (error.status === 404) { + this.thirdpartylicenses = 'File not found'; + } + } + ); - this.httpClient.get('ReleaseNotes.txt', {responseType: 'text'}) - .subscribe(data => { - this.releasenotes = data.replace(new RegExp('\n', 'g'), "
") - }); - } + this.httpClient.get('ReleaseNotes.txt', { responseType: 'text' }).subscribe((data) => { + this.releasenotes = data.replace(new RegExp('\n', 'g'), '
'); + }); + } } diff --git a/src/app/components/help/report-issue/filter.tsx b/src/app/components/help/report-issue/filter.tsx new file mode 100644 index 00000000..0ced31d4 --- /dev/null +++ b/src/app/components/help/report-issue/filter.tsx @@ -0,0 +1,24 @@ +import React, {Component} from "react"; +import Form from 'react-bootstrap/Form'; + +const formGroupStyle = { + margin: '20px' +}; + +class FilterComponent extends Component { + constructor(props) { + super(props); + } + + render() { + return ( +
+ + + +
+ ) + } +} + +export default FilterComponent; \ No newline at end of file diff --git a/src/app/components/help/report-issue/issue-list.tsx b/src/app/components/help/report-issue/issue-list.tsx new file mode 100644 index 00000000..835f6099 --- /dev/null +++ b/src/app/components/help/report-issue/issue-list.tsx @@ -0,0 +1,95 @@ +import React, { Component } from "react"; +import Card from 'react-bootstrap/Card'; +import Spinner from 'react-bootstrap/Spinner'; +import IssueComponent from './issue'; +import FilterComponent from './filter'; +import e from '../../../event-bus'; + +const wrapperStyle = { + justifyContent: 'center' as 'center', + display: 'flex', + flex: 1, + flexDirection: 'row' as 'row', + flexWrap: 'wrap' as 'wrap', + margin: '20px' +}; + +const cardStyle = { + width: '300px', + margin: '20px' +}; + +const cardTitleStyle = { + color: 'red' +}; +const message = 'Thank you for reporting the issue!'; +const apiUrl = 'https://api.github.com/repos/GNS3/gns3-web-ui/issues'; +const newIssueLink = 'https://github.com/GNS3/gns3-web-ui/issues/new'; + +class IssueListComponent extends Component { + constructor(props) { + super(props); + this.state = { + issues: [], + filteredIssues: [], + isFetching: true + }; + } + + componentDidMount() { + fetch(apiUrl) + .then(response => response.json()) + .then(data => this.setState({ + issues: data, + filteredIssues: data, + isFetching: false + })); + } + + handleChange = (event) => { + let filter = event.target.value; + let filteredIssues = this.state.issues; + + filteredIssues = filteredIssues.filter((issue) => { + return issue.title.toLowerCase().includes(filter.toLowerCase()) + }); + + this.setState({ + filteredIssues: filteredIssues + }); + } + + newIssueOpened = (event) => { + e.emit('message', { text: message }); + } + + render() { + return ( +
+
+ +
+ + {this.state.isFetching ? ( +
+ +
+ ) : ( +
+ {this.state.filteredIssues.map(issue => + + )} + + + Don't see your issue here? + Open new issue + + +
+ )} +
+ ); + } +}; + +export default IssueListComponent; \ No newline at end of file diff --git a/src/app/components/help/report-issue/issue.tsx b/src/app/components/help/report-issue/issue.tsx new file mode 100644 index 00000000..cc8e6dc7 --- /dev/null +++ b/src/app/components/help/report-issue/issue.tsx @@ -0,0 +1,42 @@ +import React, { Component } from "react"; +import Card from 'react-bootstrap/Card'; + +const cardStyle = { + width: '300px', + margin: '20px' +}; + +const cardTitleStyle = { + color: 'black' +}; + +const cardTextStyle = { + color: 'black', + overflow: 'auto', + height: '100px' +}; + +class IssueComponent extends Component { + constructor(props) { + super(props); + this.state = { + data: this.props.data + } + } + + render() { + const issue = this.state.data; + return ( + + + {issue.title} + Status: {issue.state} + {issue.body} + {issue.html_url} + + + ); + } +}; + +export default IssueComponent; \ No newline at end of file diff --git a/src/app/components/help/report-issue/report-issue.component.html b/src/app/components/help/report-issue/report-issue.component.html new file mode 100644 index 00000000..de3af182 --- /dev/null +++ b/src/app/components/help/report-issue/report-issue.component.html @@ -0,0 +1 @@ + diff --git a/src/app/components/notification-box/notification-box.component.spec.ts b/src/app/components/help/report-issue/report-issue.component.scss similarity index 100% rename from src/app/components/notification-box/notification-box.component.spec.ts rename to src/app/components/help/report-issue/report-issue.component.scss diff --git a/src/app/components/help/report-issue/report-issue.component.spec.ts b/src/app/components/help/report-issue/report-issue.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/help/report-issue/report-issue.component.tsx b/src/app/components/help/report-issue/report-issue.component.tsx new file mode 100644 index 00000000..f56212a7 --- /dev/null +++ b/src/app/components/help/report-issue/report-issue.component.tsx @@ -0,0 +1,52 @@ +import { HttpClient } from '@angular/common/http'; +import { + AfterViewInit, + Component, + ElementRef, + EventEmitter, + Input, + OnInit, + OnChanges, + OnDestroy, + Output, + SimpleChanges, + ViewChild, + ViewEncapsulation, + AfterContentInit + } from '@angular/core'; +import IssueListComponent from '../report-issue/issue-list'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import e from '../../../event-bus'; +import { ToasterService } from '../../../services/toaster.service'; + +@Component({ +selector: 'app-report-issue', +templateUrl: './report-issue.component.html', +styleUrls: ['./report-issue.component.scss'] +}) +export class ReportIssueComponent implements OnDestroy, AfterViewInit, AfterContentInit { + @ViewChild('issueListComponentContainer') containerRef: ElementRef; + + constructor(private toasterService: ToasterService) {} + + ngAfterViewInit() { + this.render(); + } + + ngAfterContentInit() { + e.on('message', message => { + this.toasterService.success(message.text); + }); + } + + ngOnDestroy() { + ReactDOM.unmountComponentAtNode(this.containerRef.nativeElement); + } + + private render() { + ReactDOM.render(
+ +
, this.containerRef.nativeElement); + } +} diff --git a/src/app/components/installed-software/install-software/install-software.component.html b/src/app/components/installed-software/install-software/install-software.component.html index dba60bbf..d6140ef6 100644 --- a/src/app/components/installed-software/install-software/install-software.component.html +++ b/src/app/components/installed-software/install-software/install-software.component.html @@ -1,3 +1,3 @@ \ No newline at end of file + diff --git a/src/app/components/installed-software/install-software/install-software.component.spec.ts b/src/app/components/installed-software/install-software/install-software.component.spec.ts index 33f9e4df..9d88320e 100644 --- a/src/app/components/installed-software/install-software/install-software.component.spec.ts +++ b/src/app/components/installed-software/install-software/install-software.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { InstallSoftwareComponent } from './install-software.component'; describe('InstallSoftwareComponent', () => { @@ -8,9 +7,8 @@ describe('InstallSoftwareComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ InstallSoftwareComponent ] - }) - .compileComponents(); + declarations: [InstallSoftwareComponent], + }).compileComponents(); })); beforeEach(() => { diff --git a/src/app/components/installed-software/install-software/install-software.component.ts b/src/app/components/installed-software/install-software/install-software.component.ts index 88733ada..7e1cd18a 100644 --- a/src/app/components/installed-software/install-software/install-software.component.ts +++ b/src/app/components/installed-software/install-software/install-software.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, Output, EventEmitter, Input, OnDestroy, OnChanges } from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output } from '@angular/core'; import { ElectronService } from 'ngx-electron'; @Component({ selector: 'app-install-software', templateUrl: './install-software.component.html', - styleUrls: ['./install-software.component.scss'] + styleUrls: ['./install-software.component.scss'], }) export class InstallSoftwareComponent implements OnInit, OnDestroy, OnChanges { @Input('software') @@ -12,14 +12,12 @@ export class InstallSoftwareComponent implements OnInit, OnDestroy, OnChanges { @Output() installedChanged = new EventEmitter(); - + public disabled = false; public readyToInstall = true; public buttonText: string; - constructor( - private electronService: ElectronService - ) { } + constructor(private electronService: ElectronService) {} ngOnInit() { this.electronService.ipcRenderer.on(this.responseChannel, (event, data) => { @@ -38,7 +36,7 @@ export class InstallSoftwareComponent implements OnInit, OnDestroy, OnChanges { install() { this.disabled = true; - this.buttonText = "Installing"; + this.buttonText = 'Installing'; this.electronService.ipcRenderer.send('installed-software-install', this.software); } @@ -50,10 +48,9 @@ export class InstallSoftwareComponent implements OnInit, OnDestroy, OnChanges { this.disabled = this.software.installed; if (this.software.installed) { - this.buttonText = "Installed"; - } - else { - this.buttonText = "Install"; + this.buttonText = 'Installed'; + } else { + this.buttonText = 'Install'; } } } diff --git a/src/app/components/installed-software/installed-software.component.html b/src/app/components/installed-software/installed-software.component.html index f81d01e4..1cd1f121 100644 --- a/src/app/components/installed-software/installed-software.component.html +++ b/src/app/components/installed-software/installed-software.component.html @@ -1,36 +1,37 @@
-
-

Installed software

-
-
-
- - - - Name - - - {{ row.name }} - +
+

Installed software

+
+
+
+ + + Name + + + {{ row.name }} + - - - - - - - - - - - - - - - - -
- + + + + + + + + + + + + + + + +
- \ No newline at end of file +
diff --git a/src/app/components/installed-software/installed-software.component.spec.ts b/src/app/components/installed-software/installed-software.component.spec.ts index c52bc58a..d1c8d2ea 100644 --- a/src/app/components/installed-software/installed-software.component.spec.ts +++ b/src/app/components/installed-software/installed-software.component.spec.ts @@ -1,5 +1,4 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - import { InstalledSoftwareComponent } from './installed-software.component'; describe('InstalledSoftwareComponent', () => { @@ -8,9 +7,8 @@ describe('InstalledSoftwareComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ InstalledSoftwareComponent ] - }) - .compileComponents(); + declarations: [InstalledSoftwareComponent], + }).compileComponents(); })); beforeEach(() => { diff --git a/src/app/components/installed-software/installed-software.component.ts b/src/app/components/installed-software/installed-software.component.ts index 8ebdb4b0..17f58e35 100644 --- a/src/app/components/installed-software/installed-software.component.ts +++ b/src/app/components/installed-software/installed-software.component.ts @@ -1,12 +1,12 @@ -import { Component, OnInit, ChangeDetectorRef } from '@angular/core'; -import { InstalledSoftwareService } from '../../services/installed-software.service'; import { DataSource } from '@angular/cdk/table'; -import { Observable, of, BehaviorSubject } from 'rxjs'; +import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { InstalledSoftwareService } from '../../services/installed-software.service'; @Component({ selector: 'app-installed-software', templateUrl: './installed-software.component.html', - styleUrls: ['./installed-software.component.scss'] + styleUrls: ['./installed-software.component.scss'], }) export class InstalledSoftwareComponent implements OnInit { dataSource: InstalledSoftwareDataSource; @@ -15,7 +15,7 @@ export class InstalledSoftwareComponent implements OnInit { constructor( private installedSoftwareService: InstalledSoftwareService, private changeDetectorRef: ChangeDetectorRef - ) { } + ) {} ngOnInit() { this.dataSource = new InstalledSoftwareDataSource(this.installedSoftwareService); @@ -32,7 +32,7 @@ export class InstalledSoftwareComponent implements OnInit { } } -export class InstalledSoftwareDataSource extends DataSource { +export class InstalledSoftwareDataSource extends DataSource { installed = new BehaviorSubject([]); constructor(private installedSoftwareService: InstalledSoftwareService) { @@ -49,9 +49,8 @@ export class InstalledSoftwareDataSource extends DataSource { refresh() { let installedSoftware = this.installedSoftwareService.list(); installedSoftware.push({ - type: 'adbutler' + type: 'adbutler', }); this.installed.next(installedSoftware); } - } diff --git a/src/app/components/notification-box/notification-box.component.html b/src/app/components/notification-box/notification-box.component.html deleted file mode 100644 index 350fe7ce..00000000 --- a/src/app/components/notification-box/notification-box.component.html +++ /dev/null @@ -1,9 +0,0 @@ -
- -
-
- - close -
-
-
diff --git a/src/app/components/notification-box/notification-box.component.scss b/src/app/components/notification-box/notification-box.component.scss deleted file mode 100644 index da396715..00000000 --- a/src/app/components/notification-box/notification-box.component.scss +++ /dev/null @@ -1,39 +0,0 @@ -.notification-box { - position: fixed; - bottom: 20px; - right: 20px; - width: 412px; - height: 108px; -} - -.content { - background-color: #263238; - padding-left: 8px; - border-left: 2px solid #0097a7; - border-right: 2px solid #0097a7; - border-bottom: 2px solid #0097a7; -} - -.lightTheme { - background-color: white!important; -} - -.close-button { - position: fixed; - bottom: 90px; - right: 30px; - cursor: pointer; -} - -.mat-icon:hover { - color: #0097a7; -} - -.check-button { - background-color: #0097a7; - margin-top: -10px; -} - -.hidden { - visibility: hidden; -} diff --git a/src/app/components/notification-box/notification-box.component.ts b/src/app/components/notification-box/notification-box.component.ts deleted file mode 100644 index e2768f54..00000000 --- a/src/app/components/notification-box/notification-box.component.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { Component, OnInit, OnDestroy, ComponentFactoryResolver, ViewContainerRef, ViewChild } from '@angular/core'; -import { timer, Observable, Subscription } from 'rxjs'; -import { ThemeService } from '../../services/theme.service'; -import { AdbutlerComponent } from '../adbutler/adbutler.component'; -import { Router } from '@angular/router'; -import { Location } from '@angular/common'; - -@Component({ - selector: 'app-notification-box', - templateUrl: './notification-box.component.html', - styleUrls: ['./notification-box.component.scss'] -}) -export class NotificationBoxComponent implements OnInit, OnDestroy { - @ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) dynamicComponentContainer; - - timer: Observable; - viewTimer: Observable; - timerSubscription: Subscription; - viewTimerSubscription: Subscription; - viewsCounter = 0; - ticks: number = 1000; - progress: number = 0; - isAdLoaded = false; - isVisible = false; - interval = 10; - - delayTime: number = 5000; - breakTime: number = 20 * 60; - isEndless: boolean = true; - - numberOfViews: number = 1; - isLightThemeEnabled: boolean = false; - - constructor( - private themeService: ThemeService, - private componentFactoryResolver: ComponentFactoryResolver, - private viewContainerRef: ViewContainerRef, - private location: Location - ) {} - - ngOnInit() { - let adbutler = localStorage.getItem('adbutler'); - var today = new Date().toISOString().substring(0, 10); - - // to show ad once a day - // if (!this.location.path().includes('nodes') && !(adbutler == today)) this.startTimer(); - - if (!this.location.path().includes('nodes')) this.startTimer(); - this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false; - } - - ngAfterViewInit() { - this.createDynamicAdComponent(); - } - - createDynamicAdComponent() : void { - const factory = this.componentFactoryResolver.resolveComponentFactory(AdbutlerComponent); - const componentRef = this.dynamicComponentContainer.createComponent(factory); - componentRef.instance.theme = this.themeService.getActualTheme() === 'light'; - componentRef.instance.onLoad.subscribe(event => { - this.onLoadingAdbutler(event); - }) - componentRef.changeDetectorRef.detectChanges(); - } - - startTimer() { - this.timer = timer(this.delayTime, 1000); - setTimeout(() => { - this.showNotification(); - }, 5000); - - this.timerSubscription = this.timer.subscribe(() => { - this.ticks++; - if (this.ticks > this.breakTime && !this.isVisible && navigator.onLine && this.isAdLoaded) { - this.ticks = 0; - this.showNotification(); - this.viewsCounter++; - if (!this.isEndless){ - if (this.viewsCounter === this.numberOfViews) { - this.timerSubscription.unsubscribe(); - } - } - } - }); - } - - onLoadingAdbutler(event) { - this.isAdLoaded = event; - } - - showNotification() { - // localStorage.setItem('adbutler', new Date().toISOString().substring(0, 10)); - - this.viewTimer = timer(0, 100); - this.progress = 0; - this.isVisible = true; - this.viewTimerSubscription = this.viewTimer.subscribe(() => { - this.progress += 1; - if (this.progress > 100) { - this.isVisible = false; - this.viewTimerSubscription.unsubscribe(); - } - }); - } - - closeNotification() { - this.isVisible = false; - } - - ngOnDestroy() { - this.timerSubscription.unsubscribe(); - this.viewTimerSubscription.unsubscribe(); - } -} diff --git a/src/app/components/page-not-found/page-not-found.component.html b/src/app/components/page-not-found/page-not-found.component.html index 0c777606..d4b33a2d 100644 --- a/src/app/components/page-not-found/page-not-found.component.html +++ b/src/app/components/page-not-found/page-not-found.component.html @@ -1,6 +1,7 @@
-
-

404 Page not found

- -
+
+
+

404 Page not found

+ +
diff --git a/src/app/components/page-not-found/page-not-found.component.scss b/src/app/components/page-not-found/page-not-found.component.scss index b3dfebed..cc26754b 100644 --- a/src/app/components/page-not-found/page-not-found.component.scss +++ b/src/app/components/page-not-found/page-not-found.component.scss @@ -1,3 +1,3 @@ div { - text-align: center + text-align: center; } diff --git a/src/app/components/page-not-found/page-not-found.component.ts b/src/app/components/page-not-found/page-not-found.component.ts index ec0871c7..db812fa7 100644 --- a/src/app/components/page-not-found/page-not-found.component.ts +++ b/src/app/components/page-not-found/page-not-found.component.ts @@ -1,10 +1,10 @@ import { Component } from '@angular/core'; @Component({ - selector: 'app-page-not-found', - templateUrl: './page-not-found.component.html', - styleUrls: ['./page-not-found.component.scss'] + selector: 'app-page-not-found', + templateUrl: './page-not-found.component.html', + styleUrls: ['./page-not-found.component.scss'], }) export class PageNotFoundComponent { - constructor(){} + constructor() {} } diff --git a/src/app/components/preferences/built-in/built-in-preferences.component.html b/src/app/components/preferences/built-in/built-in-preferences.component.html index 06e03fd3..04a5bb21 100644 --- a/src/app/components/preferences/built-in/built-in-preferences.component.html +++ b/src/app/components/preferences/built-in/built-in-preferences.component.html @@ -1,23 +1,23 @@
-
-
-

Built-in preferences

- -
+
+
+

Built-in preferences

+
-
-
- - - Ethernet hubs - - - Ethernet switches - - - Cloud nodes - - -
+
+
+
+ + + Ethernet hubs + + + Ethernet switches + + Cloud nodes +
+
diff --git a/src/app/components/preferences/built-in/built-in-preferences.component.spec.ts b/src/app/components/preferences/built-in/built-in-preferences.component.spec.ts index 13db5332..40502933 100644 --- a/src/app/components/preferences/built-in/built-in-preferences.component.spec.ts +++ b/src/app/components/preferences/built-in/built-in-preferences.component.spec.ts @@ -1,3 +1,5 @@ +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; @@ -5,43 +7,48 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { CommonModule } from '@angular/common'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; import { MockedActivatedRoute } from '../preferences.component.spec'; import { BuiltInPreferencesComponent } from './built-in-preferences.component'; describe('BuiltInPreferencesComponent', () => { - let component: BuiltInPreferencesComponent; - let fixture: ComponentFixture; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - } - ], - declarations: [ - BuiltInPreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(BuiltInPreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + let component: BuiltInPreferencesComponent; + let fixture: ComponentFixture; + let activatedRoute = new MockedActivatedRoute().get(); - it('should set correct server id', () => { - expect(component.serverId).toBe('1'); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + ], + declarations: [BuiltInPreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BuiltInPreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set correct server id', () => { + expect(component.serverId).toBe('1'); + }); }); diff --git a/src/app/components/preferences/built-in/built-in-preferences.component.ts b/src/app/components/preferences/built-in/built-in-preferences.component.ts index c4701b8c..7749d54f 100644 --- a/src/app/components/preferences/built-in/built-in-preferences.component.ts +++ b/src/app/components/preferences/built-in/built-in-preferences.component.ts @@ -1,20 +1,17 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; - @Component({ - selector: 'app-built-in-preferences', - templateUrl: './built-in-preferences.component.html', - styleUrls: ['./built-in-preferences.component.scss', '../preferences.component.scss'] + selector: 'app-built-in-preferences', + templateUrl: './built-in-preferences.component.html', + styleUrls: ['./built-in-preferences.component.scss', '../preferences.component.scss'], }) export class BuiltInPreferencesComponent implements OnInit { - public serverId: string = ""; + public serverId: string = ''; - constructor( - private route: ActivatedRoute - ) {} + constructor(private route: ActivatedRoute) {} - ngOnInit() { - this.serverId = this.route.snapshot.paramMap.get("server_id"); - } + ngOnInit() { + this.serverId = this.route.snapshot.paramMap.get('server_id'); + } } diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.html b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.html index 2b0518f9..89cf0f0c 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.html +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.html @@ -1,25 +1,33 @@
-
-
-

New cloud node template

-
+
+
+

New cloud node template

-
- - - Run the cloud node locally - Run the cloud node on the GNS3 VM - +
+
+ + + Run the cloud node locally + Run the cloud node on the GNS3 VM + -
- - - -
-
-
- - -
+
+ + + +
+ +
+ +
+
diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.spec.ts b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.spec.ts index b756b06a..7c09abe4 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.spec.ts +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.spec.ts @@ -1,102 +1,102 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; import { CloudTemplate } from '../../../../../models/templates/cloud-template'; -import { CloudNodesAddTemplateComponent } from './cloud-nodes-add-template.component'; -import { MockedServerService } from '../../../../../services/server.service.spec'; -import { MockedToasterService } from '../../../../../services/toaster.service.spec'; -import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { ServerService } from '../../../../../services/server.service'; import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../../services/template-mocks.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ComputeService } from '../../../../../services/compute.service'; -import {MockedComputeService} from '../../../../preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec' +import { ServerService } from '../../../../../services/server.service'; +import { MockedServerService } from '../../../../../services/server.service.spec'; +import { TemplateMocksService } from '../../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../../services/toaster.service.spec'; +import { MockedComputeService } from '../../../../preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec'; +import { MockedActivatedRoute } from '../../../preferences.component.spec'; +import { CloudNodesAddTemplateComponent } from './cloud-nodes-add-template.component'; export class MockedBuiltInTemplatesService { - public addTemplate(server: Server, cloudTemplate: CloudTemplate) { - return of(cloudTemplate); - } + public addTemplate(server: Server, cloudTemplate: CloudTemplate) { + return of(cloudTemplate); + } } describe('CloudNodesAddTemplateComponent', () => { - let component: CloudNodesAddTemplateComponent; - let fixture: ComponentFixture; + let component: CloudNodesAddTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let mockedToasterService = new MockedToasterService; - let mockedComputeService = new MockedComputeService(); - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/builtin/cloud-nodes', component: CloudNodesAddTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: ComputeService, useValue: mockedComputeService }, - { provide: TemplateMocksService, useClass: TemplateMocksService } - ], - declarations: [ - CloudNodesAddTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let mockedToasterService = new MockedToasterService(); + let mockedComputeService = new MockedComputeService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(CloudNodesAddTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/builtin/cloud-nodes', component: CloudNodesAddTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: ComputeService, useValue: mockedComputeService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + ], + declarations: [CloudNodesAddTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(CloudNodesAddTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call add template', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as CloudTemplate)); - component.templateName = "sample name"; - component.server = {id: 1} as Server; - component.formGroup.controls['templateName'].setValue('template name'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call add template', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as CloudTemplate)); + component.templateName = 'sample name'; + component.server = { id: 1 } as Server; + component.formGroup.controls['templateName'].setValue('template name'); - expect(mockedBuiltInTemplatesService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when template name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as CloudTemplate)); - spyOn(mockedToasterService, 'error'); - component.templateName = ""; - component.server = {id: 1} as Server; + expect(mockedBuiltInTemplatesService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when template name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as CloudTemplate)); + spyOn(mockedToasterService, 'error'); + component.templateName = ''; + component.server = { id: 1 } as Server; - expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); - expect(mockedToasterService.error).toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); + expect(mockedToasterService.error).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.ts b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.ts index 05a4592a..9910b72d 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.ts +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component.ts @@ -1,88 +1,87 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; -import { ToasterService } from '../../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../../services/template-mocks.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { CloudTemplate } from '../../../../../models/templates/cloud-template'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; -import { ComputeService } from '../../../../../services/compute.service'; import { Compute } from '../../../../../models/compute'; - +import { Server } from '../../../../../models/server'; +import { CloudTemplate } from '../../../../../models/templates/cloud-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ComputeService } from '../../../../../services/compute.service'; +import { ServerService } from '../../../../../services/server.service'; +import { TemplateMocksService } from '../../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../../services/toaster.service'; @Component({ - selector: 'app-cloud-nodes-add-template', - templateUrl: './cloud-nodes-add-template.component.html', - styleUrls: ['./cloud-nodes-add-template.component.scss', '../../../preferences.component.scss'] + selector: 'app-cloud-nodes-add-template', + templateUrl: './cloud-nodes-add-template.component.html', + styleUrls: ['./cloud-nodes-add-template.component.scss', '../../../preferences.component.scss'], }) export class CloudNodesAddTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - formGroup: FormGroup; + server: Server; + templateName: string = ''; + formGroup: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService, - private router: Router, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private formBuilder: FormBuilder, - private computeService: ComputeService - ) { - this.formGroup = this.formBuilder.group({ - templateName: new FormControl('', Validators.required) - }); + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService, + private router: Router, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private formBuilder: FormBuilder, + private computeService: ComputeService + ) { + this.formGroup = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'cloud-nodes']); + } - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'cloud-nodes']); - } - - addTemplate() { - if (!this.formGroup.invalid) { - let cloudTemplate: CloudTemplate; - - this.templateMocksService.getCloudNodeTemplate().subscribe((template: CloudTemplate) => { - cloudTemplate = template; - }); - - cloudTemplate.template_id = uuid(); - cloudTemplate.name = this.formGroup.get('templateName').value; - cloudTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - this.builtInTemplatesService.addTemplate(this.server, cloudTemplate).subscribe((cloudNodeTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + addTemplate() { + if (!this.formGroup.invalid) { + let cloudTemplate: CloudTemplate; + + this.templateMocksService.getCloudNodeTemplate().subscribe((template: CloudTemplate) => { + cloudTemplate = template; + }); + + cloudTemplate.template_id = uuid(); + cloudTemplate.name = this.formGroup.get('templateName').value; + cloudTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; + + this.builtInTemplatesService.addTemplate(this.server, cloudTemplate).subscribe((cloudNodeTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.html b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.html index 93dc2a12..e842b60a 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.html +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.html @@ -1,8 +1,7 @@ -
-
-
-

Cloud configuration

-
+
+
+
+

Cloud configuration

@@ -178,6 +177,85 @@
+ + + + {{ type }} + + + + + + + + TAP interfaces + +
+
{{ port.name }}
+

+
+ + + + +
+ + + UDP tunnels + + + + + + + + + + + + + + + + + + + + + + + + +
Name{{ element.name }}Local port{{ element.rport }}Type{{ element.rhost }}Remote port{{ element.lport }}
+
+ + + + + + + + + + + + + +
+ +
+ +
+
- + diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.spec.ts b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.spec.ts index 8e41e319..efb79a4e 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.spec.ts +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.spec.ts @@ -1,81 +1,91 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; import { CloudTemplate } from '../../../../../models/templates/cloud-template'; -import { CloudNodesTemplateDetailsComponent } from './cloud-nodes-template-details.component'; +import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { MockedServerService } from '../../../../../services/server.service.spec'; +import { ToasterService } from '../../../../../services/toaster.service'; import { MockedToasterService } from '../../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { ServerService } from '../../../../../services/server.service'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; +import { CloudNodesTemplateDetailsComponent } from './cloud-nodes-template-details.component'; export class MockedBuiltInTemplatesService { - public getTemplate(server: Server, template_id: string) { - return of({ports_mapping: []} as CloudTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({ ports_mapping: [] } as CloudTemplate); + } - public saveTemplate(server: Server, cloudTemplate: CloudTemplate) { - return of(cloudTemplate); - } + public saveTemplate(server: Server, cloudTemplate: CloudTemplate) { + return of(cloudTemplate); + } } describe('CloudNodesTemplateDetailsComponent', () => { - let component: CloudNodesTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: CloudNodesTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatTableModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: BuiltInTemplatesConfigurationService, useClass: BuiltInTemplatesConfigurationService } - ], - declarations: [ - CloudNodesTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(CloudNodesTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: BuiltInTemplatesConfigurationService, useClass: BuiltInTemplatesConfigurationService }, + ], + declarations: [CloudNodesTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(CloudNodesTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as CloudTemplate)); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.cloudNodeTemplate = {ports_mapping: []} as CloudTemplate; - component.onSave(); + it('should call save template', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as CloudTemplate)); - expect(mockedBuiltInTemplatesService.saveTemplate).toHaveBeenCalled(); - }); + component.cloudNodeTemplate = { ports_mapping: [] } as CloudTemplate; + component.onSave(); + + expect(mockedBuiltInTemplatesService.saveTemplate).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.ts b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.ts index 7705c46b..e6877a49 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.ts +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component.ts @@ -1,131 +1,131 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; -import { Server } from '../../../../../models/server'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { CloudTemplate } from '../../../../../models/templates/cloud-template'; import { PortsMappingEntity } from '../../../../../models/ethernetHub/ports-mapping-enity'; +import { Server } from '../../../../../models/server'; +import { CloudTemplate } from '../../../../../models/templates/cloud-template'; import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; - +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; +import { ToasterService } from '../../../../../services/toaster.service'; @Component({ - selector: 'app-cloud-nodes-template-details', - templateUrl: './cloud-nodes-template-details.component.html', - styleUrls: ['./cloud-nodes-template-details.component.scss', '../../../preferences.component.scss'] + selector: 'app-cloud-nodes-template-details', + templateUrl: './cloud-nodes-template-details.component.html', + styleUrls: ['./cloud-nodes-template-details.component.scss', '../../../preferences.component.scss'], }) export class CloudNodesTemplateDetailsComponent implements OnInit { - server: Server; - cloudNodeTemplate: CloudTemplate; + server: Server; + cloudNodeTemplate: CloudTemplate; - isSymbolSelectionOpened: boolean = false; + isSymbolSelectionOpened: boolean = false; - categories = []; - consoleTypes: string[] = []; + categories = []; + consoleTypes: string[] = []; - tapInterface: string = ''; - ethernetInterface: string = ''; - ethernetInterfaces: string[] = ['Ethernet 2', 'Ethernet 3']; - portsMappingEthernet: PortsMappingEntity[] = []; - portsMappingTap: PortsMappingEntity[] = []; - portsMappingUdp: PortsMappingEntity[] = []; - newPort: PortsMappingEntity; - displayedColumns: string[] = ['name', 'lport', 'rhost', 'rport']; - dataSourceUdp: PortsMappingEntity[] = []; + tapInterface: string = ''; + ethernetInterface: string = ''; + ethernetInterfaces: string[] = ['Ethernet 2', 'Ethernet 3']; + portsMappingEthernet: PortsMappingEntity[] = []; + portsMappingTap: PortsMappingEntity[] = []; + portsMappingUdp: PortsMappingEntity[] = []; + newPort: PortsMappingEntity; + displayedColumns: string[] = ['name', 'lport', 'rhost', 'rport']; + dataSourceUdp: PortsMappingEntity[] = []; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService, - private toasterService: ToasterService, - private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService, - private router: Router - ) { - this.newPort = { - name: '', - port_number: 0, - }; - } + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService, + private toasterService: ToasterService, + private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService, + private router: Router + ) { + this.newPort = { + name: '', + port_number: 0, + }; + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; - this.getConfiguration(); - this.builtInTemplatesService.getTemplate(this.server, template_id).subscribe((cloudNodeTemplate: CloudTemplate) => { - this.cloudNodeTemplate = cloudNodeTemplate; + this.getConfiguration(); + this.builtInTemplatesService + .getTemplate(this.server, template_id) + .subscribe((cloudNodeTemplate: CloudTemplate) => { + this.cloudNodeTemplate = cloudNodeTemplate; - this.portsMappingEthernet = this.cloudNodeTemplate.ports_mapping - .filter((elem) => elem.type === 'ethernet'); + this.portsMappingEthernet = this.cloudNodeTemplate.ports_mapping.filter((elem) => elem.type === 'ethernet'); - this.portsMappingTap = this.cloudNodeTemplate.ports_mapping - .filter((elem) => elem.type === 'tap'); - - this.portsMappingUdp = this.cloudNodeTemplate.ports_mapping - .filter((elem) => elem.type === 'udp'); - - this.dataSourceUdp = this.portsMappingUdp; - }); + this.portsMappingTap = this.cloudNodeTemplate.ports_mapping.filter((elem) => elem.type === 'tap'); + + this.portsMappingUdp = this.cloudNodeTemplate.ports_mapping.filter((elem) => elem.type === 'udp'); + + this.dataSourceUdp = this.portsMappingUdp; }); - } + }); + } - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'cloud-nodes']); - } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'cloud-nodes']); + } - getConfiguration() { - this.categories = this.builtInTemplatesConfigurationService.getCategoriesForCloudNodes(); - this.consoleTypes = this.builtInTemplatesConfigurationService.getConsoleTypesForCloudNodes(); - } + getConfiguration() { + this.categories = this.builtInTemplatesConfigurationService.getCategoriesForCloudNodes(); + this.consoleTypes = this.builtInTemplatesConfigurationService.getConsoleTypesForCloudNodes(); + } - onAddEthernetInterface() { - if (this.ethernetInterface) { - this.portsMappingEthernet.push({ - interface: this.ethernetInterface, - name: this.ethernetInterface, - port_number: 0, - type: "ethernet" - }); - } + onAddEthernetInterface() { + if (this.ethernetInterface) { + this.portsMappingEthernet.push({ + interface: this.ethernetInterface, + name: this.ethernetInterface, + port_number: 0, + type: 'ethernet', + }); } + } - onAddTapInterface() { - if (this.tapInterface) { - this.portsMappingTap.push({ - interface: this.tapInterface, - name: this.tapInterface, - port_number: 0, - type: "tap" - }); - } + onAddTapInterface() { + if (this.tapInterface) { + this.portsMappingTap.push({ + interface: this.tapInterface, + name: this.tapInterface, + port_number: 0, + type: 'tap', + }); } + } - onAddUdpInterface() { - this.portsMappingUdp.push(this.newPort); - this.dataSourceUdp = [...this.portsMappingUdp]; - - this.newPort = { - name: '', - port_number: 0, - }; - } + onAddUdpInterface() { + this.portsMappingUdp.push(this.newPort); + this.dataSourceUdp = [...this.portsMappingUdp]; - onSave() { - this.cloudNodeTemplate.ports_mapping = [...this.portsMappingEthernet, ...this.portsMappingTap]; + this.newPort = { + name: '', + port_number: 0, + }; + } - this.builtInTemplatesService.saveTemplate(this.server, this.cloudNodeTemplate).subscribe((cloudNodeTemplate: CloudTemplate) => { - this.toasterService.success("Changes saved"); - }); - } + onSave() { + this.cloudNodeTemplate.ports_mapping = [...this.portsMappingEthernet, ...this.portsMappingTap]; - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } + this.builtInTemplatesService + .saveTemplate(this.server, this.cloudNodeTemplate) + .subscribe((cloudNodeTemplate: CloudTemplate) => { + this.toasterService.success('Changes saved'); + }); + } - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.cloudNodeTemplate.symbol = chosenSymbol; - } + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } + + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.cloudNodeTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.html b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.html index 1fa88847..22cfab26 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.html +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.html @@ -1,32 +1,46 @@
-
-
-

Cloud nodes templates

- - -
+
+
+

Cloud nodes templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.spec.ts b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.spec.ts index b70defc0..05abbebe 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.spec.ts +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; import { CloudTemplate } from '../../../../../models/templates/cloud-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { MockedServerService } from '../../../../../services/server.service.spec'; import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { ServerService } from '../../../../../services/server.service'; import { CloudNodesTemplatesComponent } from './cloud-nodes-templates.component'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; export class MockedBuiltInTemplatesService { - public getTemplates(server: Server) { - return of([{} as CloudTemplate]); - } + public getTemplates(server: Server) { + return of([{} as CloudTemplate]); + } } describe('CloudNodesTemplatesComponent', () => { - let component: CloudNodesTemplatesComponent; - let fixture: ComponentFixture; + let component: CloudNodesTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService } - ], - declarations: [ - CloudNodesTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(CloudNodesTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + ], + declarations: [CloudNodesTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(CloudNodesTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.ts b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.ts index 7efc602c..b6e03e13 100644 --- a/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.ts +++ b/src/app/components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component.ts @@ -1,47 +1,46 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { Server } from '../../../../../models/server'; import { CloudTemplate } from '../../../../../models/templates/cloud-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { DeleteTemplateComponent } from '../../../common/delete-template-component/delete-template.component'; - @Component({ - selector: 'app-cloud-nodes-templates', - templateUrl: './cloud-nodes-templates.component.html', - styleUrls: ['./cloud-nodes-templates.component.scss', '../../../preferences.component.scss'] + selector: 'app-cloud-nodes-templates', + templateUrl: './cloud-nodes-templates.component.html', + styleUrls: ['./cloud-nodes-templates.component.scss', '../../../preferences.component.scss'], }) export class CloudNodesTemplatesComponent implements OnInit { - server: Server; - cloudNodesTemplates: CloudTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + cloudNodesTemplates: CloudTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.builtInTemplatesService.getTemplates(this.server).subscribe((cloudNodesTemplates: CloudTemplate[]) => { - this.cloudNodesTemplates = cloudNodesTemplates.filter((elem) => elem.template_type === "cloud" && !elem.builtin); - }); - } + getTemplates() { + this.builtInTemplatesService.getTemplates(this.server).subscribe((cloudNodesTemplates: CloudTemplate[]) => { + this.cloudNodesTemplates = cloudNodesTemplates.filter((elem) => elem.template_type === 'cloud' && !elem.builtin); + }); + } - deleteTemplate(template: CloudTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: CloudTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.html b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.html index 599d2221..0e90b602 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.html +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.html @@ -1,28 +1,36 @@
-
-
-

New Ethernet hub template

-
+
+
+

New Ethernet hub template

-
- - - Run the Ethernet Hub locally - Run the Ethernet Hub on the GNS3 VM - +
+
+ + + Run the Ethernet Hub locally + Run the Ethernet Hub on the GNS3 VM + -
- - - - - - -
-
-
- - -
+
+ + + + + + +
+ +
+ +
+
diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.spec.ts b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.spec.ts index 9cc2d8ff..3b1749f2 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.spec.ts +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.spec.ts @@ -1,117 +1,118 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; -import { MockedServerService } from '../../../../../services/server.service.spec'; -import { MockedToasterService } from '../../../../../services/toaster.service.spec'; -import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { ServerService } from '../../../../../services/server.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../../services/template-mocks.service'; import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; -import { EthernetHubsAddTemplateComponent } from './ethernet-hubs-add-template.component'; -import { ReactiveFormsModule, FormsModule } from '@angular/forms'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; import { ComputeService } from '../../../../../services/compute.service'; -import {MockedComputeService} from '../../../../preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec'; +import { ServerService } from '../../../../../services/server.service'; +import { MockedServerService } from '../../../../../services/server.service.spec'; +import { TemplateMocksService } from '../../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../../services/toaster.service.spec'; +import { MockedComputeService } from '../../../../preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec'; +import { MockedActivatedRoute } from '../../../preferences.component.spec'; +import { EthernetHubsAddTemplateComponent } from './ethernet-hubs-add-template.component'; export class MockedBuiltInTemplatesService { - public addTemplate(server: Server, ethernetHubTemplate: EthernetHubTemplate) { - return of(ethernetHubTemplate); - } + public addTemplate(server: Server, ethernetHubTemplate: EthernetHubTemplate) { + return of(ethernetHubTemplate); + } } describe('EthernetHubsAddTemplateComponent', () => { - let component: EthernetHubsAddTemplateComponent; - let fixture: ComponentFixture; + let component: EthernetHubsAddTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let mockedToasterService = new MockedToasterService; - let mockedComputeService = new MockedComputeService(); - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/builtin/ethernet-hubs', component: EthernetHubsAddTemplateComponent}]) - ], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: ComputeService, useValue: mockedComputeService }, - { provide: TemplateMocksService, useClass: TemplateMocksService } - ], - declarations: [ - EthernetHubsAddTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let mockedToasterService = new MockedToasterService(); + let mockedComputeService = new MockedComputeService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(EthernetHubsAddTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/builtin/ethernet-hubs', component: EthernetHubsAddTemplateComponent }, + ]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: ComputeService, useValue: mockedComputeService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + ], + declarations: [EthernetHubsAddTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EthernetHubsAddTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call add template', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetHubTemplate)); - component.templateName = "sample name"; - component.server = {id: 1} as Server; - component.formGroup.controls['templateName'].setValue('template name'); - component.formGroup.controls['numberOfPorts'].setValue('1'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call add template', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetHubTemplate)); + component.templateName = 'sample name'; + component.server = { id: 1 } as Server; + component.formGroup.controls['templateName'].setValue('template name'); + component.formGroup.controls['numberOfPorts'].setValue('1'); - expect(mockedBuiltInTemplatesService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when template name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetHubTemplate)); - spyOn(mockedToasterService, 'error'); - component.templateName = ""; - component.server = {id: 1} as Server; + expect(mockedBuiltInTemplatesService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when template name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetHubTemplate)); + spyOn(mockedToasterService, 'error'); + component.templateName = ''; + component.server = { id: 1 } as Server; - expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); - expect(mockedToasterService.error).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when number of ports is missing', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetHubTemplate)); - spyOn(mockedToasterService, 'error'); - component.templateName = "sample name"; - component.server = {id: 1} as Server; + expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); + expect(mockedToasterService.error).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when number of ports is missing', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetHubTemplate)); + spyOn(mockedToasterService, 'error'); + component.templateName = 'sample name'; + component.server = { id: 1 } as Server; - expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); - expect(mockedToasterService.error).toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); + expect(mockedToasterService.error).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.ts b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.ts index e9a2885a..7a3d4da8 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.ts +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component.ts @@ -1,96 +1,95 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; -import { ToasterService } from '../../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../../services/template-mocks.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; -import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms'; -import { ComputeService } from '../../../../../services/compute.service'; import { Compute } from '../../../../../models/compute'; - +import { Server } from '../../../../../models/server'; +import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ComputeService } from '../../../../../services/compute.service'; +import { ServerService } from '../../../../../services/server.service'; +import { TemplateMocksService } from '../../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../../services/toaster.service'; @Component({ - selector: 'app-ethernet-hubs-add-template', - templateUrl: './ethernet-hubs-add-template.component.html', - styleUrls: ['./ethernet-hubs-add-template.component.scss', '../../../preferences.component.scss'] + selector: 'app-ethernet-hubs-add-template', + templateUrl: './ethernet-hubs-add-template.component.html', + styleUrls: ['./ethernet-hubs-add-template.component.scss', '../../../preferences.component.scss'], }) export class EthernetHubsAddTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - formGroup: FormGroup; + server: Server; + templateName: string = ''; + formGroup: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService, - private router: Router, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private formBuilder: FormBuilder, - private computeService: ComputeService - ) { - this.formGroup = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - numberOfPorts: new FormControl(8, Validators.required) + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService, + private router: Router, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private formBuilder: FormBuilder, + private computeService: ComputeService + ) { + this.formGroup = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + numberOfPorts: new FormControl(8, Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; + } + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-hubs']); + } + + addTemplate() { + if (!this.formGroup.invalid) { + let ethernetHubTemplate: EthernetHubTemplate; + + this.templateMocksService.getEthernetHubTemplate().subscribe((template: EthernetHubTemplate) => { + ethernetHubTemplate = template; + }); + + ethernetHubTemplate.template_id = uuid(); + ethernetHubTemplate.name = this.formGroup.get('templateName').value; + ethernetHubTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; + + for (let i = 0; i < this.formGroup.get('numberOfPorts').value; i++) { + ethernetHubTemplate.ports_mapping.push({ + name: `Ethernet${i}`, + port_number: i, }); + } + + this.builtInTemplatesService.addTemplate(this.server, ethernetHubTemplate).subscribe(() => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-hubs']); - } - - addTemplate() { - if (!this.formGroup.invalid) { - let ethernetHubTemplate: EthernetHubTemplate; - - this.templateMocksService.getEthernetHubTemplate().subscribe((template: EthernetHubTemplate) => { - ethernetHubTemplate = template; - }); - - ethernetHubTemplate.template_id = uuid(); - ethernetHubTemplate.name = this.formGroup.get('templateName').value; - ethernetHubTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - for(let i=0; i { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } - } + } } diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.html b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.html index 1a75e798..b33932f2 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.html +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.html @@ -1,57 +1,71 @@ -
-
-
-

Ethernet hub settings

-
+
+
+
+

Ethernet hub settings

-
- -
- - - - - - - - - -

- - - - {{category[0]}} - - - - - - -
-
-
- -
-
+
+
+ +
+ + + + + + + + + +

+ + + + {{ category[0] }} + + + + + + +
+
+
+ +
+
- + diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.spec.ts b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.spec.ts index 558001a6..28476feb 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.spec.ts +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.spec.ts @@ -1,124 +1,134 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; +import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; +import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { MockedServerService } from '../../../../../services/server.service.spec'; +import { ToasterService } from '../../../../../services/toaster.service'; import { MockedToasterService } from '../../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { ServerService } from '../../../../../services/server.service'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; import { EthernetHubsTemplateDetailsComponent } from './ethernet-hubs-template-details.component'; -import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; export class MockedBuiltInTemplatesService { - public getTemplate(server: Server, template_id: string) { - return of({ports_mapping: []} as EthernetHubTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({ ports_mapping: [] } as EthernetHubTemplate); + } - public saveTemplate(server: Server, cloudTemplate: EthernetHubTemplate) { - return of(cloudTemplate); - } + public saveTemplate(server: Server, cloudTemplate: EthernetHubTemplate) { + return of(cloudTemplate); + } } describe('EthernetHubsTemplateDetailsComponent', () => { - let component: EthernetHubsTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: EthernetHubsTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatTableModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: BuiltInTemplatesConfigurationService, useClass: BuiltInTemplatesConfigurationService } - ], - declarations: [ - EthernetHubsTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(EthernetHubsTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: BuiltInTemplatesConfigurationService, useClass: BuiltInTemplatesConfigurationService }, + ], + declarations: [EthernetHubsTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EthernetHubsTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); - component.numberOfPorts = 2; - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue('symbol'); - component.ethernetHubTemplate = {ports_mapping: []} as EthernetHubTemplate; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); + component.numberOfPorts = 2; + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['symbol'].setValue('symbol'); + component.ethernetHubTemplate = { ports_mapping: [] } as EthernetHubTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when template name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); - component.numberOfPorts = 2; - component.inputForm.controls['templateName'].setValue(''); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue('symbol'); - component.ethernetHubTemplate = {ports_mapping: []} as EthernetHubTemplate; + expect(mockedBuiltInTemplatesService.saveTemplate).toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when template name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); + component.numberOfPorts = 2; + component.inputForm.controls['templateName'].setValue(''); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['symbol'].setValue('symbol'); + component.ethernetHubTemplate = { ports_mapping: [] } as EthernetHubTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when default name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); - component.numberOfPorts = 2; - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue(''); - component.inputForm.controls['symbol'].setValue('symbol'); - component.ethernetHubTemplate = {ports_mapping: []} as EthernetHubTemplate; + expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when default name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); + component.numberOfPorts = 2; + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue(''); + component.inputForm.controls['symbol'].setValue('symbol'); + component.ethernetHubTemplate = { ports_mapping: [] } as EthernetHubTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should call save template when symbol path is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); - component.numberOfPorts = 2; - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue(''); - component.ethernetHubTemplate = {ports_mapping: []} as EthernetHubTemplate; + expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should call save template when symbol path is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetHubTemplate)); + component.numberOfPorts = 2; + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['symbol'].setValue(''); + component.ethernetHubTemplate = { ports_mapping: [] } as EthernetHubTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.ts b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.ts index cf30ac85..146617b9 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.ts +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component.ts @@ -1,86 +1,89 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; import { Server } from '../../../../../models/server'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; - +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; +import { ToasterService } from '../../../../../services/toaster.service'; @Component({ - selector: 'app-ethernet-hubs-template-details', - templateUrl: './ethernet-hubs-template-details.component.html', - styleUrls: ['./ethernet-hubs-template-details.component.scss', '../../../preferences.component.scss'] + selector: 'app-ethernet-hubs-template-details', + templateUrl: './ethernet-hubs-template-details.component.html', + styleUrls: ['./ethernet-hubs-template-details.component.scss', '../../../preferences.component.scss'], }) export class EthernetHubsTemplateDetailsComponent implements OnInit { - server: Server; - ethernetHubTemplate: EthernetHubTemplate; - numberOfPorts: number; - inputForm: FormGroup; - isSymbolSelectionOpened: boolean = false; + server: Server; + ethernetHubTemplate: EthernetHubTemplate; + numberOfPorts: number; + inputForm: FormGroup; + isSymbolSelectionOpened: boolean = false; - categories = []; + categories = []; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService, - private router: Router - ) { - this.inputForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService, + private router: Router + ) { + this.inputForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.categories = this.builtInTemplatesConfigurationService.getCategoriesForEthernetHubs(); + this.builtInTemplatesService + .getTemplate(this.server, template_id) + .subscribe((ethernetHubTemplate: EthernetHubTemplate) => { + this.ethernetHubTemplate = ethernetHubTemplate; + this.numberOfPorts = this.ethernetHubTemplate.ports_mapping.length; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-hubs']); + } + + onSave() { + if (this.inputForm.invalid || !this.numberOfPorts) { + this.toasterService.error(`Fill all required fields`); + } else { + this.ethernetHubTemplate.ports_mapping = []; + for (let i = 0; i < this.numberOfPorts; i++) { + this.ethernetHubTemplate.ports_mapping.push({ + name: `Ethernet${i}`, + port_number: i, + }); + } + + this.builtInTemplatesService + .saveTemplate(this.server, this.ethernetHubTemplate) + .subscribe((ethernetHubTemplate: EthernetHubTemplate) => { + this.toasterService.success('Changes saved'); }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - this.categories = this.builtInTemplatesConfigurationService.getCategoriesForEthernetHubs(); - this.builtInTemplatesService.getTemplate(this.server, template_id).subscribe((ethernetHubTemplate: EthernetHubTemplate) => { - this.ethernetHubTemplate = ethernetHubTemplate; - this.numberOfPorts = this.ethernetHubTemplate.ports_mapping.length; - }); - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-hubs']); - } - - onSave() { - if (this.inputForm.invalid || ! this.numberOfPorts) { - this.toasterService.error(`Fill all required fields`); - } else { - this.ethernetHubTemplate.ports_mapping = []; - for(let i=0; i { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.ethernetHubTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.ethernetHubTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.html b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.html index d7f87d39..f83b36a4 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.html +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.html @@ -1,32 +1,46 @@
-
-
-

Ethernet hubs templates

- - -
+
+
+

Ethernet hubs templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.spec.ts b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.spec.ts index 7deb83f9..4fe7cd5f 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.spec.ts +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; +import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { MockedServerService } from '../../../../../services/server.service.spec'; import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { ServerService } from '../../../../../services/server.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; import { EthernetHubsTemplatesComponent } from './ethernet-hubs-templates.component'; export class MockedBuiltInTemplatesService { - public getTemplates(server: Server) { - return of([{} as EthernetHubTemplate]); - } + public getTemplates(server: Server) { + return of([{} as EthernetHubTemplate]); + } } describe('EthernetHubsTemplatesComponent', () => { - let component: EthernetHubsTemplatesComponent; - let fixture: ComponentFixture; + let component: EthernetHubsTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService } - ], - declarations: [ - EthernetHubsTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(EthernetHubsTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + ], + declarations: [EthernetHubsTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EthernetHubsTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.ts b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.ts index 02dfd070..98eda9c0 100644 --- a/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.ts +++ b/src/app/components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component.ts @@ -1,47 +1,48 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; +import { Server } from '../../../../../models/server'; import { EthernetHubTemplate } from '../../../../../models/templates/ethernet-hub-template'; import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { DeleteTemplateComponent } from '../../../common/delete-template-component/delete-template.component'; - @Component({ - selector: 'app-ethernet-hubs-templates', - templateUrl: './ethernet-hubs-templates.component.html', - styleUrls: ['./ethernet-hubs-templates.component.scss', '../../../preferences.component.scss'] + selector: 'app-ethernet-hubs-templates', + templateUrl: './ethernet-hubs-templates.component.html', + styleUrls: ['./ethernet-hubs-templates.component.scss', '../../../preferences.component.scss'], }) export class EthernetHubsTemplatesComponent implements OnInit { - server: Server; - ethernetHubsTemplates: EthernetHubTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + ethernetHubsTemplates: EthernetHubTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.builtInTemplatesService.getTemplates(this.server).subscribe((ethernetHubsTemplates: EthernetHubTemplate[]) => { - this.ethernetHubsTemplates = ethernetHubsTemplates.filter((elem) => elem.template_type === "ethernet_hub" && !elem.builtin); - }); - } - - deleteTemplate(template: EthernetHubTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + getTemplates() { + this.builtInTemplatesService.getTemplates(this.server).subscribe((ethernetHubsTemplates: EthernetHubTemplate[]) => { + this.ethernetHubsTemplates = ethernetHubsTemplates.filter( + (elem) => elem.template_type === 'ethernet_hub' && !elem.builtin + ); + }); + } - onDeleteEvent() { - this.getTemplates(); - } + deleteTemplate(template: EthernetHubTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } + + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.html b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.html index 1620b6f2..ca42cf47 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.html +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.html @@ -1,28 +1,36 @@
-
-
-

New Ethernet switch template

-
+
+
+

New Ethernet switch template

-
- - - Run the Ethernet switch locally - Run the Ethernet switch on the GNS3 VM - +
+
+ + + Run the Ethernet switch locally + Run the Ethernet switch on the GNS3 VM + -
- - - - - - -
-
-
- - -
+
+ + + + + + +
+ +
+ +
+
diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.spec.ts b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.spec.ts index c11f2fe7..f2dffb92 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.spec.ts +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.spec.ts @@ -1,117 +1,118 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; -import { MockedServerService } from '../../../../../services/server.service.spec'; -import { MockedToasterService } from '../../../../../services/toaster.service.spec'; -import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { ServerService } from '../../../../../services/server.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../../services/template-mocks.service'; import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; -import { EthernetSwitchesAddTemplateComponent } from './ethernet-switches-add-template.component'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; import { ComputeService } from '../../../../../services/compute.service'; -import {MockedComputeService} from '../../../../preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec'; +import { ServerService } from '../../../../../services/server.service'; +import { MockedServerService } from '../../../../../services/server.service.spec'; +import { TemplateMocksService } from '../../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../../services/toaster.service.spec'; +import { MockedComputeService } from '../../../../preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec'; +import { MockedActivatedRoute } from '../../../preferences.component.spec'; +import { EthernetSwitchesAddTemplateComponent } from './ethernet-switches-add-template.component'; export class MockedBuiltInTemplatesService { - public addTemplate(server: Server, ethernetHubTemplate: EthernetSwitchTemplate) { - return of(ethernetHubTemplate); - } + public addTemplate(server: Server, ethernetHubTemplate: EthernetSwitchTemplate) { + return of(ethernetHubTemplate); + } } describe('EthernetSwitchesAddTemplateComponent', () => { - let component: EthernetSwitchesAddTemplateComponent; - let fixture: ComponentFixture; + let component: EthernetSwitchesAddTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let mockedToasterService = new MockedToasterService; - let mockedComputeService = new MockedComputeService(); - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/builtin/ethernet-switches', component: EthernetSwitchesAddTemplateComponent}]) - ], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: ComputeService, useValue: mockedComputeService }, - { provide: TemplateMocksService, useClass: TemplateMocksService } - ], - declarations: [ - EthernetSwitchesAddTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let mockedToasterService = new MockedToasterService(); + let mockedComputeService = new MockedComputeService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(EthernetSwitchesAddTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/builtin/ethernet-switches', component: EthernetSwitchesAddTemplateComponent }, + ]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: ComputeService, useValue: mockedComputeService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + ], + declarations: [EthernetSwitchesAddTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EthernetSwitchesAddTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call add template', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - component.templateName = "sample name"; - component.server = {id: 1} as Server; - component.formGroup.controls['templateName'].setValue('template name'); - component.formGroup.controls['numberOfPorts'].setValue('1'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call add template', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + component.templateName = 'sample name'; + component.server = { id: 1 } as Server; + component.formGroup.controls['templateName'].setValue('template name'); + component.formGroup.controls['numberOfPorts'].setValue('1'); - expect(mockedBuiltInTemplatesService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when template name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - spyOn(mockedToasterService, 'error'); - component.formGroup.controls['numberOfPorts'].setValue('1'); - component.server = {id: 1} as Server; + expect(mockedBuiltInTemplatesService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when template name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + spyOn(mockedToasterService, 'error'); + component.formGroup.controls['numberOfPorts'].setValue('1'); + component.server = { id: 1 } as Server; - expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); - expect(mockedToasterService.error).toHaveBeenCalled(); - }); + component.addTemplate(); - xit('should not call add template when number of ports is missing', () => { - spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - spyOn(mockedToasterService, 'error'); - component.formGroup.controls['templateName'].setValue('template name'); - component.server = {id: 1} as Server; + expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); + expect(mockedToasterService.error).toHaveBeenCalled(); + }); - component.addTemplate(); + xit('should not call add template when number of ports is missing', () => { + spyOn(mockedBuiltInTemplatesService, 'addTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + spyOn(mockedToasterService, 'error'); + component.formGroup.controls['templateName'].setValue('template name'); + component.server = { id: 1 } as Server; - expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); - expect(mockedToasterService.error).toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedBuiltInTemplatesService.addTemplate).not.toHaveBeenCalled(); + expect(mockedToasterService.error).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.ts b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.ts index 9ea693c3..4bfd638c 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.ts +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component.ts @@ -1,99 +1,100 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; -import { ToasterService } from '../../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../../services/template-mocks.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; -import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; -import { ComputeService } from '../../../../../services/compute.service'; import { Compute } from '../../../../../models/compute'; - +import { Server } from '../../../../../models/server'; +import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ComputeService } from '../../../../../services/compute.service'; +import { ServerService } from '../../../../../services/server.service'; +import { TemplateMocksService } from '../../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../../services/toaster.service'; @Component({ - selector: 'app-ethernet-switches-add-template', - templateUrl: './ethernet-switches-add-template.component.html', - styleUrls: ['./ethernet-switches-add-template.component.scss', '../../../preferences.component.scss'] + selector: 'app-ethernet-switches-add-template', + templateUrl: './ethernet-switches-add-template.component.html', + styleUrls: ['./ethernet-switches-add-template.component.scss', '../../../preferences.component.scss'], }) export class EthernetSwitchesAddTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - formGroup: FormGroup; + server: Server; + templateName: string = ''; + formGroup: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService, - private router: Router, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private formBuilder: FormBuilder, - private computeService: ComputeService - ) { - this.formGroup = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - numberOfPorts: new FormControl(8, Validators.required) + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService, + private router: Router, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private formBuilder: FormBuilder, + private computeService: ComputeService + ) { + this.formGroup = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + numberOfPorts: new FormControl(8, Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-switches']); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; + } + } + + addTemplate() { + if (!this.formGroup.invalid) { + let ethernetSwitchTemplate: EthernetSwitchTemplate; + + this.templateMocksService.getEthernetSwitchTemplate().subscribe((template: EthernetSwitchTemplate) => { + ethernetSwitchTemplate = template; + }); + + ethernetSwitchTemplate.template_id = uuid(); + ethernetSwitchTemplate.name = this.formGroup.get('templateName').value; + ethernetSwitchTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; + + for (let i = 0; i < this.formGroup.get('numberOfPorts').value; i++) { + ethernetSwitchTemplate.ports_mapping.push({ + ethertype: '', + name: `Ethernet${i}`, + port_number: i, + type: 'access', + vlan: 1, }); - } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); + this.builtInTemplatesService + .addTemplate(this.server, ethernetSwitchTemplate) + .subscribe((ethernetSwitchTemplate) => { + this.goBack(); }); + } else { + this.toasterService.error(`Fill all required fields`); } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-switches']); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - addTemplate() { - if (!this.formGroup.invalid) { - let ethernetSwitchTemplate: EthernetSwitchTemplate; - - this.templateMocksService.getEthernetSwitchTemplate().subscribe((template: EthernetSwitchTemplate) => { - ethernetSwitchTemplate = template; - }); - - ethernetSwitchTemplate.template_id = uuid(); - ethernetSwitchTemplate.name = this.formGroup.get('templateName').value; - ethernetSwitchTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - for(let i=0; i { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } - } + } } diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.html b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.html index 8089383b..1de6293c 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.html +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.html @@ -1,75 +1,84 @@ -
-
-
-

Ethernet switch configuration

-
+
+
+
+

Ethernet switch configuration

-
- - - - - General settings - - -
- - - - - - - - - -

- - - - {{category[0]}} - - - - - - - {{type}} - - - -
-
- - - - Port settings - - - - -
-
- - -
+
+
+ + + + General settings + +
+ + + + + + + + + +

+ + + + {{ category[0] }} + + + + + + + {{ type }} + + + +
+
+ + + Port settings + + + +
+
+ +
+
- + diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.spec.ts b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.spec.ts index 3c8162c7..ab69568a 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.spec.ts +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.spec.ts @@ -1,122 +1,132 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; -import { MockedServerService } from '../../../../../services/server.service.spec'; -import { MockedToasterService } from '../../../../../services/toaster.service.spec'; -import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { ServerService } from '../../../../../services/server.service'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; -import { EthernetSwitchesTemplateDetailsComponent } from './ethernet-switches-template-details.component'; import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; +import { MockedServerService } from '../../../../../services/server.service.spec'; +import { ToasterService } from '../../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../../services/toaster.service.spec'; import { PortsComponent } from '../../../common/ports/ports.component'; +import { MockedActivatedRoute } from '../../../preferences.component.spec'; +import { EthernetSwitchesTemplateDetailsComponent } from './ethernet-switches-template-details.component'; export class MockedBuiltInTemplatesService { - public getTemplate(server: Server, template_id: string) { - return of({ports_mapping: []} as EthernetSwitchTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({ ports_mapping: [] } as EthernetSwitchTemplate); + } - public saveTemplate(server: Server, cloudTemplate: EthernetSwitchTemplate) { - return of(cloudTemplate); - } + public saveTemplate(server: Server, cloudTemplate: EthernetSwitchTemplate) { + return of(cloudTemplate); + } } describe('EthernetSwitchesTemplateDetailsComponent', () => { - let component: EthernetSwitchesTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: EthernetSwitchesTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatTableModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: BuiltInTemplatesConfigurationService, useClass: BuiltInTemplatesConfigurationService } - ], - declarations: [ - EthernetSwitchesTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(EthernetSwitchesTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: BuiltInTemplatesConfigurationService, useClass: BuiltInTemplatesConfigurationService }, + ], + declarations: [EthernetSwitchesTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EthernetSwitchesTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - component.portsComponent = {ethernetPorts: []} as PortsComponent; - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue('symbol'); - component.ethernetSwitchTemplate = {ports_mapping: []} as EthernetSwitchTemplate; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + component.portsComponent = { ethernetPorts: [] } as PortsComponent; + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['symbol'].setValue('symbol'); + component.ethernetSwitchTemplate = { ports_mapping: [] } as EthernetSwitchTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when template name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - component.inputForm.controls['templateName'].setValue(''); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue('symbol'); - component.ethernetSwitchTemplate = {ports_mapping: []} as EthernetSwitchTemplate; + expect(mockedBuiltInTemplatesService.saveTemplate).toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when template name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + component.inputForm.controls['templateName'].setValue(''); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['symbol'].setValue('symbol'); + component.ethernetSwitchTemplate = { ports_mapping: [] } as EthernetSwitchTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when default name is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue(''); - component.inputForm.controls['symbol'].setValue('symbol'); - component.ethernetSwitchTemplate = {ports_mapping: []} as EthernetSwitchTemplate; + expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when default name is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue(''); + component.inputForm.controls['symbol'].setValue('symbol'); + component.ethernetSwitchTemplate = { ports_mapping: [] } as EthernetSwitchTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when symbol path is empty', () => { - spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue(''); - component.ethernetSwitchTemplate = {ports_mapping: []} as EthernetSwitchTemplate; + expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when symbol path is empty', () => { + spyOn(mockedBuiltInTemplatesService, 'saveTemplate').and.returnValue(of({} as EthernetSwitchTemplate)); + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['symbol'].setValue(''); + component.ethernetSwitchTemplate = { ports_mapping: [] } as EthernetSwitchTemplate; - expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedBuiltInTemplatesService.saveTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.ts b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.ts index 290da59f..8a68b1da 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.ts +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component.ts @@ -1,84 +1,87 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; import { Server } from '../../../../../models/server'; -import { ToasterService } from '../../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; import { BuiltInTemplatesConfigurationService } from '../../../../../services/built-in-templates-configuration.service'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; +import { ToasterService } from '../../../../../services/toaster.service'; import { PortsComponent } from '../../../common/ports/ports.component'; - @Component({ - selector: 'app-ethernet-switches-template-details', - templateUrl: './ethernet-switches-template-details.component.html', - styleUrls: ['./ethernet-switches-template-details.component.scss', '../../../preferences.component.scss'] + selector: 'app-ethernet-switches-template-details', + templateUrl: './ethernet-switches-template-details.component.html', + styleUrls: ['./ethernet-switches-template-details.component.scss', '../../../preferences.component.scss'], }) export class EthernetSwitchesTemplateDetailsComponent implements OnInit { - @ViewChild(PortsComponent) portsComponent: PortsComponent; - server: Server; - ethernetSwitchTemplate: EthernetSwitchTemplate; - inputForm: FormGroup; - isSymbolSelectionOpened: boolean = false; - categories = []; - consoleTypes: string[] = []; + @ViewChild(PortsComponent) portsComponent: PortsComponent; + server: Server; + ethernetSwitchTemplate: EthernetSwitchTemplate; + inputForm: FormGroup; + isSymbolSelectionOpened: boolean = false; + categories = []; + consoleTypes: string[] = []; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService, - private router: Router - ){ - this.inputForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService, + private router: Router + ) { + this.inputForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.builtInTemplatesService + .getTemplate(this.server, template_id) + .subscribe((ethernetSwitchTemplate: EthernetSwitchTemplate) => { + this.ethernetSwitchTemplate = ethernetSwitchTemplate; + }); + }); + } + + getConfiguration() { + this.categories = this.builtInTemplatesConfigurationService.getCategoriesForEthernetSwitches(); + this.consoleTypes = this.builtInTemplatesConfigurationService.getConsoleTypesForEthernetSwitches(); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-switches']); + } + + onSave() { + if (this.inputForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.ethernetSwitchTemplate.ports_mapping = this.portsComponent.ethernetPorts; + this.builtInTemplatesService + .saveTemplate(this.server, this.ethernetSwitchTemplate) + .subscribe((ethernetSwitchTemplate: EthernetSwitchTemplate) => { + this.toasterService.success('Changes saved'); }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - this.getConfiguration(); - this.builtInTemplatesService.getTemplate(this.server, template_id).subscribe((ethernetSwitchTemplate: EthernetSwitchTemplate) => { - this.ethernetSwitchTemplate = ethernetSwitchTemplate; - }); - }); - } - - getConfiguration() { - this.categories = this.builtInTemplatesConfigurationService.getCategoriesForEthernetSwitches(); - this.consoleTypes = this.builtInTemplatesConfigurationService.getConsoleTypesForEthernetSwitches(); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'builtin', 'ethernet-switches']); - } - - onSave() { - if (this.inputForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.ethernetSwitchTemplate.ports_mapping = this.portsComponent.ethernetPorts; - this.builtInTemplatesService.saveTemplate(this.server, this.ethernetSwitchTemplate).subscribe((ethernetSwitchTemplate: EthernetSwitchTemplate) => { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.ethernetSwitchTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.ethernetSwitchTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.html b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.html index 9b59ddc5..73017e63 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.html +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.html @@ -1,32 +1,46 @@
-
-
-

Ethernet switches templates

- - -
+
+
+

Ethernet switches templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.spec.ts b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.spec.ts index f6a088ad..abb9459b 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.spec.ts +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Server } from '../../../../../models/server'; +import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { MockedServerService } from '../../../../../services/server.service.spec'; import { MockedActivatedRoute } from '../../../preferences.component.spec'; -import { ServerService } from '../../../../../services/server.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; import { EthernetSwitchesTemplatesComponent } from './ethernet-switches-templates.component'; -import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; export class MockedBuiltInTemplatesService { - public getTemplates(server: Server) { - return of([{} as EthernetSwitchTemplate]); - } + public getTemplates(server: Server) { + return of([{} as EthernetSwitchTemplate]); + } } describe('EthernetSwitchesTemplatesComponent', () => { - let component: EthernetSwitchesTemplatesComponent; - let fixture: ComponentFixture; + let component: EthernetSwitchesTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService } - ], - declarations: [ - EthernetSwitchesTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedBuiltInTemplatesService = new MockedBuiltInTemplatesService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(EthernetSwitchesTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: BuiltInTemplatesService, useValue: mockedBuiltInTemplatesService }, + ], + declarations: [EthernetSwitchesTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EthernetSwitchesTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.ts b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.ts index b29092b3..2c9fa941 100644 --- a/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.ts +++ b/src/app/components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component.ts @@ -1,47 +1,50 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ServerService } from '../../../../../services/server.service'; -import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { Server } from '../../../../../models/server'; import { EthernetSwitchTemplate } from '../../../../../models/templates/ethernet-switch-template'; +import { BuiltInTemplatesService } from '../../../../../services/built-in-templates.service'; +import { ServerService } from '../../../../../services/server.service'; import { DeleteTemplateComponent } from '../../../common/delete-template-component/delete-template.component'; - @Component({ - selector: 'app-ethernet-switches-templates', - templateUrl: './ethernet-switches-templates.component.html', - styleUrls: ['./ethernet-switches-templates.component.scss', '../../../preferences.component.scss'] + selector: 'app-ethernet-switches-templates', + templateUrl: './ethernet-switches-templates.component.html', + styleUrls: ['./ethernet-switches-templates.component.scss', '../../../preferences.component.scss'], }) export class EthernetSwitchesTemplatesComponent implements OnInit { - server: Server; - ethernetSwitchesTemplates: EthernetSwitchTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + ethernetSwitchesTemplates: EthernetSwitchTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private builtInTemplatesService: BuiltInTemplatesService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private builtInTemplatesService: BuiltInTemplatesService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.builtInTemplatesService.getTemplates(this.server).subscribe((ethernetSwitchesTemplates: EthernetSwitchTemplate[]) => { - this.ethernetSwitchesTemplates = ethernetSwitchesTemplates.filter((elem) => elem.template_type === "ethernet_switch" && !elem.builtin); - }); - } - - deleteTemplate(template: EthernetSwitchTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + getTemplates() { + this.builtInTemplatesService + .getTemplates(this.server) + .subscribe((ethernetSwitchesTemplates: EthernetSwitchTemplate[]) => { + this.ethernetSwitchesTemplates = ethernetSwitchesTemplates.filter( + (elem) => elem.template_type === 'ethernet_switch' && !elem.builtin + ); + }); + } - onDeleteEvent() { - this.getTemplates(); - } + deleteTemplate(template: EthernetSwitchTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } + + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.html b/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.html index 1a782d13..7fecbe05 100644 --- a/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.html +++ b/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.html @@ -1,35 +1,35 @@ - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - + + + + + + +
Adapter number Adapter {{element.adapter_number}} Adapter numberAdapter {{ element.adapter_number }} Port name Ethernet {{element.adapter_number}} Port nameEthernet {{ element.adapter_number }} Adapter type - - - {{type}} - - - Adapter type + + + {{ type }} + + + Actions - -
Actions + +
diff --git a/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.ts b/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.ts index f9ad5452..ea34cf46 100644 --- a/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.ts +++ b/src/app/components/preferences/common/custom-adapters-table/custom-adapters-table.component.ts @@ -1,28 +1,27 @@ -import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; - @Component({ - selector: 'app-custom-adapters-table', - templateUrl: './custom-adapters-table.component.html', - styleUrls: ['../../preferences.component.scss'] + selector: 'app-custom-adapters-table', + templateUrl: './custom-adapters-table.component.html', + styleUrls: ['../../preferences.component.scss'], }) export class CustomAdaptersTableComponent { - @Input() networkTypes = []; - @Input() displayedColumns: string[] = []; - @Input() adapters: CustomAdapter[] = []; + @Input() networkTypes = []; + @Input() displayedColumns: string[] = []; + @Input() adapters: CustomAdapter[] = []; - public numberOfAdapters: number; + public numberOfAdapters: number; - onAdd() { - let adapter: CustomAdapter = { - adapter_number: this.adapters.length, - adapter_type: this.networkTypes[0] - } - this.adapters = this.adapters.concat([adapter]); - } + onAdd() { + let adapter: CustomAdapter = { + adapter_number: this.adapters.length, + adapter_type: this.networkTypes[0], + }; + this.adapters = this.adapters.concat([adapter]); + } - delete(adapter: CustomAdapter) { - this.adapters = this.adapters.filter(elem => elem!== adapter); - } + delete(adapter: CustomAdapter) { + this.adapters = this.adapters.filter((elem) => elem !== adapter); + } } diff --git a/src/app/components/preferences/common/custom-adapters/custom-adapters.component.html b/src/app/components/preferences/common/custom-adapters/custom-adapters.component.html index 53e1855b..be5e47c5 100644 --- a/src/app/components/preferences/common/custom-adapters/custom-adapters.component.html +++ b/src/app/components/preferences/common/custom-adapters/custom-adapters.component.html @@ -1,21 +1,21 @@
-
-
-

Custom adapters configuration

-
+
+
+

Custom adapters configuration

-
-
- -
-
- -
-
+
+
+
+
+
+ +
+
+
diff --git a/src/app/components/preferences/common/custom-adapters/custom-adapters.component.spec.ts b/src/app/components/preferences/common/custom-adapters/custom-adapters.component.spec.ts index 85edc7ee..1bcd2b99 100644 --- a/src/app/components/preferences/common/custom-adapters/custom-adapters.component.spec.ts +++ b/src/app/components/preferences/common/custom-adapters/custom-adapters.component.spec.ts @@ -1,3 +1,5 @@ +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; @@ -5,49 +7,53 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { CommonModule } from '@angular/common'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { CustomAdaptersComponent } from './custom-adapters.component'; import { CustomAdaptersTableComponent } from '../custom-adapters-table/custom-adapters-table.component'; +import { CustomAdaptersComponent } from './custom-adapters.component'; describe('Custom adapters component', () => { - let component: CustomAdaptersComponent; - let fixture: ComponentFixture; + let component: CustomAdaptersComponent; + let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatTableModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule], - declarations: [ - CustomAdaptersComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(CustomAdaptersComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + ], + declarations: [CustomAdaptersComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should emit event when apply clicked', () => { - spyOn(component.saveConfigurationEmitter, 'emit'); - component.customAdapters = {adapters: []} as CustomAdaptersTableComponent; + beforeEach(() => { + fixture = TestBed.createComponent(CustomAdaptersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - component.configureCustomAdapters(); + it('should create', () => { + expect(component).toBeTruthy(); + }); - expect(component.saveConfigurationEmitter.emit).toHaveBeenCalled(); - }); + it('should emit event when apply clicked', () => { + spyOn(component.saveConfigurationEmitter, 'emit'); + component.customAdapters = { adapters: [] } as CustomAdaptersTableComponent; - it('should emit event when cancel clicked', () => { - spyOn(component.closeConfiguratorEmitter, 'emit'); + component.configureCustomAdapters(); - component.cancelConfigureCustomAdapters(); + expect(component.saveConfigurationEmitter.emit).toHaveBeenCalled(); + }); - expect(component.closeConfiguratorEmitter.emit).toHaveBeenCalled(); - }); + it('should emit event when cancel clicked', () => { + spyOn(component.closeConfiguratorEmitter, 'emit'); + + component.cancelConfigureCustomAdapters(); + + expect(component.closeConfiguratorEmitter.emit).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/common/custom-adapters/custom-adapters.component.ts b/src/app/components/preferences/common/custom-adapters/custom-adapters.component.ts index 9eac1689..d9d92362 100644 --- a/src/app/components/preferences/common/custom-adapters/custom-adapters.component.ts +++ b/src/app/components/preferences/common/custom-adapters/custom-adapters.component.ts @@ -1,43 +1,42 @@ -import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; import { CustomAdaptersTableComponent } from '../custom-adapters-table/custom-adapters-table.component'; - @Component({ - selector: 'app-custom-adapters', - templateUrl: './custom-adapters.component.html', - styleUrls: ['./custom-adapters.component.scss', '../../preferences.component.scss'] + selector: 'app-custom-adapters', + templateUrl: './custom-adapters.component.html', + styleUrls: ['./custom-adapters.component.scss', '../../preferences.component.scss'], }) export class CustomAdaptersComponent { - @Input() networkTypes = []; - @Input() displayedColumns: string[] = []; - @Output() closeConfiguratorEmitter = new EventEmitter(); - @Output() saveConfigurationEmitter = new EventEmitter(); + @Input() networkTypes = []; + @Input() displayedColumns: string[] = []; + @Output() closeConfiguratorEmitter = new EventEmitter(); + @Output() saveConfigurationEmitter = new EventEmitter(); - @ViewChild("customAdapters") customAdapters: CustomAdaptersTableComponent; + @ViewChild('customAdapters') customAdapters: CustomAdaptersTableComponent; - public adapters: CustomAdapter[]; - public numberOfAdapters: number; + public adapters: CustomAdapter[]; + public numberOfAdapters: number; - constructor() { - console.log(this.networkTypes); - } + constructor() { + console.log(this.networkTypes); + } - cancelConfigureCustomAdapters(){ - this.closeConfiguratorEmitter.emit(false); - } + cancelConfigureCustomAdapters() { + this.closeConfiguratorEmitter.emit(false); + } - configureCustomAdapters(){ - this.adapters = []; - console.log(this.customAdapters); - - this.customAdapters.adapters.forEach(n => { - this.adapters.push({ - adapter_number: n.adapter_number, - adapter_type: n.adapter_type - }) - }); + configureCustomAdapters() { + this.adapters = []; + console.log(this.customAdapters); - this.saveConfigurationEmitter.emit(this.adapters); - } + this.customAdapters.adapters.forEach((n) => { + this.adapters.push({ + adapter_number: n.adapter_number, + adapter_type: n.adapter_type, + }); + }); + + this.saveConfigurationEmitter.emit(this.adapters); + } } diff --git a/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.html b/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.html index 398d83de..9406945f 100644 --- a/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.html +++ b/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.html @@ -1,15 +1,13 @@
-

Delete template

-
Are you sure you want to delete template {{templateName}}?
+

Delete template

+
Are you sure you want to delete template {{ templateName }}?
-
+
-
- - -
+
+ + +
diff --git a/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.scss b/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.scss index 9f3d3c71..fe8a2a82 100644 --- a/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.scss +++ b/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.scss @@ -1,9 +1,9 @@ .dialogcontainer { - height: 100%; - display: flex; - flex-direction: column; + height: 100%; + display: flex; + flex-direction: column; } .spacer { - flex-grow: 1; + flex-grow: 1; } diff --git a/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.ts b/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.ts index 011d2b67..70612b1f 100644 --- a/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.ts +++ b/src/app/components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component.ts @@ -1,29 +1,28 @@ -import { Component, OnInit, Inject } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; - @Component({ - selector: 'app-delete-confirmation-dialog', - templateUrl: './delete-confirmation-dialog.component.html', - styleUrls: ['./delete-confirmation-dialog.component.scss'] + selector: 'app-delete-confirmation-dialog', + templateUrl: './delete-confirmation-dialog.component.html', + styleUrls: ['./delete-confirmation-dialog.component.scss'], }) export class DeleteConfirmationDialogComponent implements OnInit { - templateName: string = ''; + templateName: string = ''; - constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: any - ) { - this.templateName = data['templateName']; - } + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.templateName = data['templateName']; + } - ngOnInit() {} + ngOnInit() {} - onNoClick(): void { - this.dialogRef.close(false); - } - - onYesClick(): void { - this.dialogRef.close(true); - } + onNoClick(): void { + this.dialogRef.close(false); + } + + onYesClick(): void { + this.dialogRef.close(true); + } } diff --git a/src/app/components/preferences/common/delete-template-component/delete-template.component.ts b/src/app/components/preferences/common/delete-template-component/delete-template.component.ts index 20965394..e0299dc2 100644 --- a/src/app/components/preferences/common/delete-template-component/delete-template.component.ts +++ b/src/app/components/preferences/common/delete-template-component/delete-template.component.ts @@ -1,43 +1,43 @@ -import { Component, Input, Output, EventEmitter } from "@angular/core"; -import { TemplateService } from '../../../../services/template.service'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { DeleteConfirmationDialogComponent } from '../delete-confirmation-dialog/delete-confirmation-dialog.component'; -import { ToasterService } from '../../../../services/toaster.service'; import { Server } from '../../../../models/server'; +import { TemplateService } from '../../../../services/template.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { DeleteConfirmationDialogComponent } from '../delete-confirmation-dialog/delete-confirmation-dialog.component'; @Component({ - selector: 'app-delete-template', - templateUrl: './delete-template.component.html', - styleUrls: ['./delete-template.component.scss'] + selector: 'app-delete-template', + templateUrl: './delete-template.component.html', + styleUrls: ['./delete-template.component.scss'], }) export class DeleteTemplateComponent { - @Input() server: Server; - @Output() deleteEvent = new EventEmitter(); - - constructor( - private templateService: TemplateService, - private dialog: MatDialog, - private toasterService: ToasterService - ) {} + @Input() server: Server; + @Output() deleteEvent = new EventEmitter(); - deleteItem(templateName, templateId) { - const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, { - width: '300px', - height: '250px', - data: { - templateName: templateName - }, - autoFocus: false, - disableClose: true + constructor( + private templateService: TemplateService, + private dialog: MatDialog, + private toasterService: ToasterService + ) {} + + deleteItem(templateName, templateId) { + const dialogRef = this.dialog.open(DeleteConfirmationDialogComponent, { + width: '300px', + height: '250px', + data: { + templateName: templateName, + }, + autoFocus: false, + disableClose: true, + }); + + dialogRef.afterClosed().subscribe((answer: boolean) => { + if (answer) { + this.templateService.deleteTemplate(this.server, templateId).subscribe((answer) => { + this.deleteEvent.emit(templateId); + this.toasterService.success(`Template ${templateName} deleted.`); }); - - dialogRef.afterClosed().subscribe((answer: boolean) => { - if (answer) { - this.templateService.deleteTemplate(this.server, templateId).subscribe((answer) => { - this.deleteEvent.emit(templateId); - this.toasterService.success(`Template ${templateName} deleted.`); - }); - } - }); - } + } + }); + } } diff --git a/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.html b/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.html index 3d523072..28073ce9 100644 --- a/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.html +++ b/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.html @@ -1,7 +1,7 @@
- -
- {{emptyTemplatesListMessage}} -
-
+ +
+ {{ emptyTemplatesListMessage }} +
+
diff --git a/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.scss b/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.scss index f867b0c4..f28eabf5 100644 --- a/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.scss +++ b/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.scss @@ -1,4 +1,4 @@ .header { - text-align: center; - color: darkgray; + text-align: center; + color: darkgray; } diff --git a/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.ts b/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.ts index c8bec4d1..7a321184 100644 --- a/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.ts +++ b/src/app/components/preferences/common/empty-templates-list/empty-templates-list.component.ts @@ -1,18 +1,17 @@ -import { Component, Input } from "@angular/core"; - +import { Component, Input } from '@angular/core'; @Component({ - selector: 'app-empty-templates-list', - templateUrl: './empty-templates-list.component.html', - styleUrls: ['./empty-templates-list.component.scss'] + selector: 'app-empty-templates-list', + templateUrl: './empty-templates-list.component.html', + styleUrls: ['./empty-templates-list.component.scss'], }) export class EmptyTemplatesListComponent { - @Input() textMessage: string; - emptyTemplatesListMessage: string = 'Empty templates list'; + @Input() textMessage: string; + emptyTemplatesListMessage: string = 'Empty templates list'; - constructor(){ - if (this.textMessage) { - this.emptyTemplatesListMessage = this.textMessage; - } + constructor() { + if (this.textMessage) { + this.emptyTemplatesListMessage = this.textMessage; } + } } diff --git a/src/app/components/preferences/common/ports/ports.component.html b/src/app/components/preferences/common/ports/ports.component.html index e7b0a8ba..8caa33d3 100644 --- a/src/app/components/preferences/common/ports/ports.component.html +++ b/src/app/components/preferences/common/ports/ports.component.html @@ -1,66 +1,55 @@ - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - -
Port number {{element.port_number}} Port number{{ element.port_number }} VLAN {{element.vlan}} VLAN{{ element.vlan }} Type {{element.type}} Type{{ element.type }} EtherType {{element.ethertype}} EtherType{{ element.ethertype }} Actions - -

+ + Actions + + + + + + + + +
- + - + - - - {{type}} - - + + + {{ type }} + + - - - {{type}} - - + + + {{ type }} + + diff --git a/src/app/components/preferences/common/ports/ports.component.ts b/src/app/components/preferences/common/ports/ports.component.ts index efc2d393..638da78c 100644 --- a/src/app/components/preferences/common/ports/ports.component.ts +++ b/src/app/components/preferences/common/ports/ports.component.ts @@ -1,48 +1,44 @@ -import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, Input, OnInit } from '@angular/core'; import { PortsMappingEntity } from '../../../../models/ethernetHub/ports-mapping-enity'; import { BuiltInTemplatesConfigurationService } from '../../../../services/built-in-templates-configuration.service'; - @Component({ - selector: 'app-ports', - templateUrl: './ports.component.html', - styleUrls: ['../../preferences.component.scss'] + selector: 'app-ports', + templateUrl: './ports.component.html', + styleUrls: ['../../preferences.component.scss'], }) export class PortsComponent implements OnInit { - @Input() ethernetPorts: PortsMappingEntity[] = []; - newPort: PortsMappingEntity = { - name: '', - port_number: 0, + @Input() ethernetPorts: PortsMappingEntity[] = []; + newPort: PortsMappingEntity = { + name: '', + port_number: 0, + }; + + portTypes: string[] = []; + etherTypes: string[] = []; + displayedColumns: string[] = ['port_number', 'vlan', 'type', 'ethertype', 'action']; + + constructor(private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService) {} + + ngOnInit() { + this.getConfiguration(); + } + + getConfiguration() { + this.etherTypes = this.builtInTemplatesConfigurationService.getEtherTypesForEthernetSwitches(); + this.portTypes = this.builtInTemplatesConfigurationService.getPortTypesForEthernetSwitches(); + } + + onAdd() { + this.ethernetPorts.push(this.newPort); + + this.newPort = { + name: '', + port_number: 0, }; + } - portTypes: string[] = []; - etherTypes: string[] = []; - displayedColumns: string[] = ['port_number', 'vlan', 'type', 'ethertype', 'action']; - - constructor( - private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService - ) {} - - ngOnInit() { - this.getConfiguration(); - } - - getConfiguration() { - this.etherTypes = this.builtInTemplatesConfigurationService.getEtherTypesForEthernetSwitches(); - this.portTypes = this.builtInTemplatesConfigurationService.getPortTypesForEthernetSwitches(); - } - - onAdd() { - this.ethernetPorts.push(this.newPort); - - this.newPort = { - name: '', - port_number: 0, - }; - } - - delete(port: PortsMappingEntity) { - this.ethernetPorts = this.ethernetPorts.filter(n => n !== port); - } + delete(port: PortsMappingEntity) { + this.ethernetPorts = this.ethernetPorts.filter((n) => n !== port); + } } diff --git a/src/app/components/preferences/common/symbols-menu/symbols-menu.component.html b/src/app/components/preferences/common/symbols-menu/symbols-menu.component.html index 4bd37758..b727fa15 100644 --- a/src/app/components/preferences/common/symbols-menu/symbols-menu.component.html +++ b/src/app/components/preferences/common/symbols-menu/symbols-menu.component.html @@ -1,12 +1,12 @@
-
-
-

Symbol selection

- - -
-
-
- +
+
+

Symbol selection

+ +
+
+
+ +
diff --git a/src/app/components/preferences/common/symbols-menu/symbols-menu.component.ts b/src/app/components/preferences/common/symbols-menu/symbols-menu.component.ts index 0b01fc92..15e6024b 100644 --- a/src/app/components/preferences/common/symbols-menu/symbols-menu.component.ts +++ b/src/app/components/preferences/common/symbols-menu/symbols-menu.component.ts @@ -1,28 +1,27 @@ -import { Component, Input, Output, EventEmitter } from "@angular/core"; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Server } from '../../../../models/server'; - @Component({ - selector: 'app-symbols-menu', - templateUrl: './symbols-menu.component.html', - styleUrls: ['./symbols-menu.component.scss', '../../preferences.component.scss'] + selector: 'app-symbols-menu', + templateUrl: './symbols-menu.component.html', + styleUrls: ['./symbols-menu.component.scss', '../../preferences.component.scss'], }) export class SymbolsMenuComponent { - @Input() server: Server; - @Input() symbol: string; - @Output() symbolChangedEmitter = new EventEmitter(); - - chosenSymbol: string = ''; + @Input() server: Server; + @Input() symbol: string; + @Output() symbolChangedEmitter = new EventEmitter(); - symbolChanged(chosenSymbol: string) { - this.chosenSymbol = chosenSymbol; - } + chosenSymbol: string = ''; - chooseSymbol() { - this.symbolChangedEmitter.emit(this.chosenSymbol); - } + symbolChanged(chosenSymbol: string) { + this.chosenSymbol = chosenSymbol; + } - cancelChooseSymbol() { - this.symbolChangedEmitter.emit(this.symbol); - } + chooseSymbol() { + this.symbolChangedEmitter.emit(this.chosenSymbol); + } + + cancelChooseSymbol() { + this.symbolChangedEmitter.emit(this.symbol); + } } diff --git a/src/app/components/preferences/common/symbols/symbols.component.html b/src/app/components/preferences/common/symbols/symbols.component.html index 2b2e0cec..c9c11bd4 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.html +++ b/src/app/components/preferences/common/symbols/symbols.component.html @@ -1,32 +1,39 @@
- - - + + +
-
- -
+
+ +
diff --git a/src/app/components/preferences/common/symbols/symbols.component.scss b/src/app/components/preferences/common/symbols/symbols.component.scss index b149705f..608fc79d 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.scss +++ b/src/app/components/preferences/common/symbols/symbols.component.scss @@ -1,60 +1,60 @@ .buttonWrapper { - width: 85px; - height: 85px; - display: flex; - align-items: center; - margin-left: auto; - margin-right: auto; - outline: none; + width: 85px; + height: 85px; + display: flex; + align-items: center; + margin-left: auto; + margin-right: auto; + outline: none; } .menu { - display: flex; - justify-content: space-between; + display: flex; + justify-content: space-between; } .button { - background: border-box; - border-width: 0px; - outline: none; + background: border-box; + border-width: 0px; + outline: none; } .buttonSelected { - border-width: 3px; - background: #0097a7!important; + border-width: 3px; + background: #0097a7 !important; } .image { - width: 65px; - height: 65px; - filter: invert(0); - --webkit-filter: invert(0)!important; + width: 65px; + height: 65px; + filter: invert(0); + --webkit-filter: invert(0) !important; } .imageSelected { - margin-left: 0px; + margin-left: 0px; } .wrapper { - display: grid; - grid-template-rows: auto; - grid-template-columns: repeat(7, 1fr); - grid-row-gap: 3em; - grid-column-gap: 1em; + display: grid; + grid-template-rows: auto; + grid-template-columns: repeat(7, 1fr); + grid-row-gap: 3em; + grid-column-gap: 1em; } .radio-selection { - width: 90%; + width: 90%; } .mat-radio-button ~ .mat-radio-button { - margin-left: 16px; + margin-left: 16px; } .non-visible { - display: none; + display: none; } .example-full-width { - width: 100%; + width: 100%; } diff --git a/src/app/components/preferences/common/symbols/symbols.component.spec.ts b/src/app/components/preferences/common/symbols/symbols.component.spec.ts index 90e24452..19cb0fea 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.spec.ts +++ b/src/app/components/preferences/common/symbols/symbols.component.spec.ts @@ -1,65 +1,72 @@ +import { CommonModule } from '@angular/common'; +import { HttpClientModule } from '@angular/common/http'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { of } from 'rxjs'; -import { CommonModule } from '@angular/common'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; -import { SymbolsComponent } from './symbols.component'; -import { SymbolService } from '../../../../services/symbol.service'; -import { HttpClientModule } from '@angular/common/http'; +import { of } from 'rxjs'; import { SearchFilter } from '../../../../filters/searchFilter.pipe'; +import { SymbolService } from '../../../../services/symbol.service'; +import { SymbolsComponent } from './symbols.component'; export class MockedSymbolService { - public list() { - return of([]); - } + public list() { + return of([]); + } - public raw() { - return of('') - } + public raw() { + return of(''); + } } describe('Symbols component', () => { - let component: SymbolsComponent; - let fixture: ComponentFixture; - let mockedSymbolsService = new MockedSymbolService; + let component: SymbolsComponent; + let fixture: ComponentFixture; + let mockedSymbolsService = new MockedSymbolService(); - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [HttpClientModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: SymbolService, useValue: mockedSymbolsService - } - ], - declarations: [ - SymbolsComponent, - SearchFilter - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(SymbolsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: SymbolService, + useValue: mockedSymbolsService, + }, + ], + declarations: [SymbolsComponent, SearchFilter], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should emit event when symbol selected', () => { - spyOn(component.symbolChanged, 'emit'); + beforeEach(() => { + fixture = TestBed.createComponent(SymbolsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - component.setSelected('id'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - expect(component.symbolChanged.emit).toHaveBeenCalled(); - expect(component.isSelected).toBe('id'); - }); + it('should emit event when symbol selected', () => { + spyOn(component.symbolChanged, 'emit'); + + component.setSelected('id'); + + expect(component.symbolChanged.emit).toHaveBeenCalled(); + expect(component.isSelected).toBe('id'); + }); }); diff --git a/src/app/components/preferences/common/symbols/symbols.component.ts b/src/app/components/preferences/common/symbols/symbols.component.ts index 98728b33..7dbbb527 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.ts +++ b/src/app/components/preferences/common/symbols/symbols.component.ts @@ -1,83 +1,82 @@ -import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core"; -import { SymbolService } from '../../../../services/symbol.service'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Server } from '../../../../models/server'; import { Symbol } from '../../../../models/symbol'; - +import { SymbolService } from '../../../../services/symbol.service'; @Component({ - selector: 'app-symbols', - templateUrl: './symbols.component.html', - styleUrls: ['./symbols.component.scss'] + selector: 'app-symbols', + templateUrl: './symbols.component.html', + styleUrls: ['./symbols.component.scss'], }) export class SymbolsComponent implements OnInit { - @Input() server: Server; - @Input() symbol: string; - @Output() symbolChanged = new EventEmitter(); - - symbols: Symbol[] = []; - filteredSymbols: Symbol[] = []; - isSelected: string = ''; - searchText: string = ''; + @Input() server: Server; + @Input() symbol: string; + @Output() symbolChanged = new EventEmitter(); - constructor( - private symbolService: SymbolService - ) {} + symbols: Symbol[] = []; + filteredSymbols: Symbol[] = []; + isSelected: string = ''; + searchText: string = ''; - ngOnInit() { - this.isSelected = this.symbol; + constructor(private symbolService: SymbolService) {} + + ngOnInit() { + this.isSelected = this.symbol; + this.loadSymbols(); + } + + setFilter(filter: string) { + if (filter === 'all') { + this.filteredSymbols = this.symbols; + } else if (filter === 'builtin') { + this.filteredSymbols = this.symbols.filter((elem) => elem.builtin); + } else { + this.filteredSymbols = this.symbols.filter((elem) => !elem.builtin); + } + } + + setSelected(symbol_id: string) { + this.isSelected = symbol_id; + this.symbolChanged.emit(this.isSelected); + } + + loadSymbols() { + this.symbolService.list(this.server).subscribe((symbols: Symbol[]) => { + this.symbols = symbols; + this.filteredSymbols = symbols; + }); + } + + public uploadSymbolFile(event) { + this.readSymbolFile(event.target); + } + + private readSymbolFile(symbolInput) { + let file: File = symbolInput.files[0]; + let fileName = symbolInput.files[0].name; + let fileReader: FileReader = new FileReader(); + let imageToUpload = new Image(); + + fileReader.onloadend = () => { + let image = fileReader.result; + let svg = this.createSvgFileForImage(image, imageToUpload); + this.symbolService.add(this.server, fileName, svg).subscribe(() => { this.loadSymbols(); - } + }); + }; - setFilter(filter: string) { - if (filter === 'all') { - this.filteredSymbols = this.symbols; - } else if (filter === 'builtin') { - this.filteredSymbols = this.symbols.filter(elem => elem.builtin); - } else { - this.filteredSymbols = this.symbols.filter(elem => !elem.builtin); - } - } + imageToUpload.onload = () => { + fileReader.readAsDataURL(file); + }; + imageToUpload.src = window.URL.createObjectURL(file); + } - setSelected(symbol_id: string) { - this.isSelected = symbol_id; - this.symbolChanged.emit(this.isSelected); - } + private createSvgFileForImage(image: string | ArrayBuffer, imageToUpload: HTMLImageElement) { + return `\n\n`; + } - loadSymbols() { - this.symbolService.list(this.server).subscribe((symbols: Symbol[]) => { - this.symbols = symbols; - this.filteredSymbols = symbols; - }); - } - - public uploadSymbolFile(event) { - this.readSymbolFile(event.target); - } - - private readSymbolFile(symbolInput) { - let file: File = symbolInput.files[0]; - let fileName = symbolInput.files[0].name; - let fileReader: FileReader = new FileReader(); - let imageToUpload = new Image(); - - fileReader.onloadend = () => { - let image = fileReader.result; - let svg = this.createSvgFileForImage(image, imageToUpload); - this.symbolService.add(this.server, fileName, svg).subscribe(() => { - this.loadSymbols(); - }); - } - - imageToUpload.onload = () => { fileReader.readAsDataURL(file) }; - imageToUpload.src = window.URL.createObjectURL(file); - } - - private createSvgFileForImage(image: string|ArrayBuffer, imageToUpload: HTMLImageElement) { - return `\n\n` - } - - getImageSourceForTemplate(symbol: string) { - return `${this.server.protocol}//${this.server.host}:${this.server.port}/v2/symbols/${symbol}/raw`; - } + getImageSourceForTemplate(symbol: string) { + return `${this.server.protocol}//${this.server.host}:${this.server.port}/v2/symbols/${symbol}/raw`; + } } diff --git a/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.html b/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.html index 4c319918..5778607a 100644 --- a/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.html +++ b/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.html @@ -1,59 +1,47 @@ - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - + + + + + + +
Name {{element.name}} Name{{ element.name }} Local port {{element.rport}} Local port{{ element.rport }} Type {{element.rhost}} Type{{ element.rhost }} Remote port {{element.lport}} Remote port{{ element.lport }} Actions - -
Actions + +
-
+
- + - + - + - + diff --git a/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.ts b/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.ts index 6052b28c..b027f58b 100644 --- a/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.ts +++ b/src/app/components/preferences/common/udp-tunnels/udp-tunnels.component.ts @@ -1,47 +1,43 @@ -import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, Input, OnInit } from '@angular/core'; import { PortsMappingEntity } from '../../../../models/ethernetHub/ports-mapping-enity'; import { BuiltInTemplatesConfigurationService } from '../../../../services/built-in-templates-configuration.service'; - @Component({ - selector: 'app-udp-tunnels', - templateUrl: './udp-tunnels.component.html', - styleUrls: ['../../preferences.component.scss'] + selector: 'app-udp-tunnels', + templateUrl: './udp-tunnels.component.html', + styleUrls: ['../../preferences.component.scss'], }) export class UdpTunnelsComponent implements OnInit { - @Input() dataSourceUdp: PortsMappingEntity[] = []; - displayedColumns: string[] = ['name', 'lport', 'rhost', 'rport', 'action']; - newPort: PortsMappingEntity = { - name: '', - port_number: 0, + @Input() dataSourceUdp: PortsMappingEntity[] = []; + displayedColumns: string[] = ['name', 'lport', 'rhost', 'rport', 'action']; + newPort: PortsMappingEntity = { + name: '', + port_number: 0, + }; + portTypes: string[] = []; + etherTypes: string[] = []; + + constructor(private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService) {} + + ngOnInit() { + this.getConfiguration(); + } + + getConfiguration() { + this.etherTypes = this.builtInTemplatesConfigurationService.getEtherTypesForEthernetSwitches(); + this.portTypes = this.builtInTemplatesConfigurationService.getPortTypesForEthernetSwitches(); + } + + onAddUdpInterface() { + this.dataSourceUdp = this.dataSourceUdp.concat([this.newPort]); + + this.newPort = { + name: '', + port_number: 0, }; - portTypes: string[] = []; - etherTypes: string[] = []; + } - constructor( - private builtInTemplatesConfigurationService: BuiltInTemplatesConfigurationService - ) {} - - ngOnInit() { - this.getConfiguration(); - } - - getConfiguration() { - this.etherTypes = this.builtInTemplatesConfigurationService.getEtherTypesForEthernetSwitches(); - this.portTypes = this.builtInTemplatesConfigurationService.getPortTypesForEthernetSwitches(); - } - - onAddUdpInterface() { - this.dataSourceUdp = this.dataSourceUdp.concat([this.newPort]); - - this.newPort = { - name: '', - port_number: 0, - }; - } - - delete(port: PortsMappingEntity) { - this.dataSourceUdp = this.dataSourceUdp.filter(n => n !== port); - } + delete(port: PortsMappingEntity) { + this.dataSourceUdp = this.dataSourceUdp.filter((n) => n !== port); + } } diff --git a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html index b4cd79c2..6742275e 100644 --- a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html +++ b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html @@ -1,105 +1,109 @@
-
-
-

New Docker container template

-
+
+
+

New Docker container template

-
-
- - - - - Run this Docker container locally - Run this Docker container on the GNS3 VM - - +
+
+
+ + + + + Run this Docker container locally + Run this Docker container on the GNS3 VM + + - -
- - Existing image - New image - - - - {{image.image}} - - -
- - - -
-
-
+ +
+ + Existing image + New image + + + + {{ image.image }} + + +
+ + + +
+
+
- -
- - - -
-
+ +
+ + + +
+
- -
- - - -
-
+ +
+ + + +
+
- - - - - + + + + + - - - - {{type}} - - - + + + + {{ type }} + + + - - - - - -
-
-
- - -
+ + + + + +
+
+ + +
+
diff --git a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.spec.ts b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.spec.ts index 1f206fce..879c8ae4 100644 --- a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.spec.ts +++ b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.spec.ts @@ -1,4 +1,6 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { AbstractControlDirective, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatCommonModule } from '@angular/material/core'; @@ -11,204 +13,189 @@ import { MatSelectModule } from '@angular/material/select'; import { MatStepperModule } from '@angular/material/stepper'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; +import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { ActivatedRoute, Route } from '@angular/router'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; +import { DockerTemplate } from '../../../../models/templates/docker-template'; +import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; +import { DockerService } from '../../../../services/docker.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule, AbstractControlDirective, FormControl } from '@angular/forms'; -import { DockerTemplate } from '../../../../models/templates/docker-template'; import { AddDockerTemplateComponent } from './add-docker-template.component'; -import { DockerService } from '../../../../services/docker.service'; -import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; -import { StepperOrientation, STEPPER_GLOBAL_OPTIONS, STEP_STATE, CdkStep } from '@angular/cdk/stepper'; -import { By } from '@angular/platform-browser'; export class MockedDockerService { - public addTemplate(server: Server, dockerTemplate: DockerTemplate) { - return of(dockerTemplate); - } + public addTemplate(server: Server, dockerTemplate: DockerTemplate) { + return of(dockerTemplate); + } } //Tests disabled due to instability xdescribe('AddDockerTemplateComponent', () => { - let component: AddDockerTemplateComponent; - let fixture: ComponentFixture; + let component: AddDockerTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedDockerService = new MockedDockerService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - MatStepperModule, - MatAutocompleteModule, - MatCommonModule, - MatRadioModule, - FormsModule, - MatTableModule, - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - ReactiveFormsModule, - MatSelectModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/docker/templates', component: AddDockerTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: DockerService, useValue: mockedDockerService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: TemplateMocksService, useClass: TemplateMocksService }, - { provide: DockerConfigurationService, useClass: DockerConfigurationService }, - { provide: AbstractControlDirective, useExisting: FormControl, useMulti: true }, - ], - declarations: [ - AddDockerTemplateComponent - ] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedDockerService = new MockedDockerService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(AddDockerTemplateComponent); - component = fixture.componentInstance; + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatStepperModule, + MatAutocompleteModule, + MatCommonModule, + MatRadioModule, + FormsModule, + MatTableModule, + MatAutocompleteModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule, + MatSelectModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/docker/templates', component: AddDockerTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: DockerService, useValue: mockedDockerService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + { provide: DockerConfigurationService, useClass: DockerConfigurationService }, + { provide: AbstractControlDirective, useExisting: FormControl, useMulti: true }, + ], + declarations: [AddDockerTemplateComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddDockerTemplateComponent); + component = fixture.componentInstance; + }); + + afterEach(() => { + fixture.destroy(); + }); + + it('should open first step at start', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + let stepperComponent = fixture.debugElement.query(By.css('mat-vertical-stepper')).componentInstance; + + expect(stepperComponent.selectedIndex).toBe(0); }); + })); - afterEach(() => { - fixture.destroy(); + it('should display correct label at start', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + let selectedLabel = fixture.nativeElement.querySelector('[aria-selected="true"]'); + + expect(selectedLabel.textContent).toMatch('Server type'); }); + })); - it('should open first step at start', async(() => { + it('should not call add template when required fields are empty', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + let addButton = fixture.debugElement.nativeElement.querySelector('.add-button'); + spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate)); + + addButton.click(); + + expect(component.virtualMachineForm.invalid).toBe(true); + expect(component.containerNameForm.invalid).toBe(true); + expect(component.networkAdaptersForm.invalid).toBe(true); + + expect(mockedDockerService.addTemplate).not.toHaveBeenCalled(); + }); + })); + + it('should call add template when required fields are filled', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + let stepperComponent = fixture.debugElement.query(By.css('mat-vertical-stepper')).componentInstance; + stepperComponent.selectedIndex = 1; + component.newImageSelected = true; + + fixture.detectChanges(); + fixture.whenStable().then(() => { + let selectedLabel = fixture.nativeElement.querySelector('[aria-selected="true"]'); + + expect(selectedLabel.textContent).toMatch('Docker Virtual Machine'); + + let filenameInput = fixture.debugElement.nativeElement.querySelector('.filename'); + filenameInput.value = 'sample filename'; + filenameInput.dispatchEvent(new Event('input')); fixture.detectChanges(); fixture.whenStable().then(() => { - let stepperComponent = fixture.debugElement - .query(By.css('mat-vertical-stepper')).componentInstance; + expect(component.dockerTemplate.image).toBe('sample filename'); - expect(stepperComponent.selectedIndex).toBe(0); - }); - })); + expect(component.virtualMachineForm.invalid).toBe(false); + expect(component.containerNameForm.invalid).toBe(true); - it('should display correct label at start', async(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - let selectedLabel = fixture.nativeElement - .querySelector('[aria-selected="true"]'); + stepperComponent.selectedIndex = 2; + fixture.detectChanges(); + fixture.whenStable().then(() => { + selectedLabel = fixture.nativeElement.querySelector('[aria-selected="true"]'); - expect(selectedLabel.textContent).toMatch('Server type'); - }); - })); - - it('should not call add template when required fields are empty', async(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - let addButton = fixture.debugElement.nativeElement - .querySelector('.add-button'); - spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate)); - - addButton.click(); - - expect(component.virtualMachineForm.invalid).toBe(true); - expect(component.containerNameForm.invalid).toBe(true); - expect(component.networkAdaptersForm.invalid).toBe(true); - - expect(mockedDockerService.addTemplate).not.toHaveBeenCalled(); - }); - })); - - it('should call add template when required fields are filled', async(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - let stepperComponent = fixture.debugElement - .query(By.css('mat-vertical-stepper')).componentInstance; - stepperComponent.selectedIndex = 1; - component.newImageSelected = true; + expect(selectedLabel.textContent).toMatch('Container name'); + let templatenameInput = fixture.debugElement.nativeElement.querySelector('.templatename'); + templatenameInput.value = 'sample templatename'; + templatenameInput.dispatchEvent(new Event('input')); fixture.detectChanges(); fixture.whenStable().then(() => { - let selectedLabel = fixture.nativeElement - .querySelector('[aria-selected="true"]'); + expect(component.dockerTemplate.name).toBe('sample templatename'); - expect(selectedLabel.textContent).toMatch('Docker Virtual Machine'); + expect(component.virtualMachineForm.invalid).toBe(false); + expect(component.containerNameForm.invalid).toBe(false); - let filenameInput = fixture.debugElement.nativeElement - .querySelector('.filename'); - filenameInput.value = 'sample filename'; - filenameInput.dispatchEvent(new Event('input')); + stepperComponent.selectedIndex = 3; + fixture.detectChanges(); + fixture.whenStable().then(() => { + selectedLabel = fixture.nativeElement.querySelector('[aria-selected="true"]'); + + expect(selectedLabel.textContent).toMatch('Network adapters'); + + let networkadapterInput = fixture.debugElement.nativeElement.querySelector('.networkadapter'); + networkadapterInput.value = 2; + networkadapterInput.dispatchEvent(new Event('input')); fixture.detectChanges(); fixture.whenStable().then(() => { - expect(component.dockerTemplate.image).toBe('sample filename'); + expect(component.dockerTemplate.adapters).toBe(2); - expect(component.virtualMachineForm.invalid).toBe(false); - expect(component.containerNameForm.invalid).toBe(true); + expect(component.virtualMachineForm.invalid).toBe(false); + expect(component.containerNameForm.invalid).toBe(false); + expect(component.networkAdaptersForm.invalid).toBe(false); - stepperComponent.selectedIndex = 2; - fixture.detectChanges(); - fixture.whenStable().then(() => { - selectedLabel = fixture.nativeElement - .querySelector('[aria-selected="true"]'); + let addButton = fixture.debugElement.nativeElement.querySelector('.add-button'); + spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate)); - expect(selectedLabel.textContent).toMatch('Container name'); + addButton.click(); - let templatenameInput = fixture.debugElement.nativeElement - .querySelector('.templatename'); - templatenameInput.value = 'sample templatename'; - templatenameInput.dispatchEvent(new Event('input')); - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(component.dockerTemplate.name).toBe('sample templatename'); - - expect(component.virtualMachineForm.invalid).toBe(false); - expect(component.containerNameForm.invalid).toBe(false); - - stepperComponent.selectedIndex = 3; - fixture.detectChanges(); - fixture.whenStable().then(() => { - selectedLabel = fixture.nativeElement - .querySelector('[aria-selected="true"]'); - - expect(selectedLabel.textContent).toMatch('Network adapters'); - - let networkadapterInput = fixture.debugElement.nativeElement - .querySelector('.networkadapter'); - networkadapterInput.value = 2; - networkadapterInput.dispatchEvent(new Event('input')); - fixture.detectChanges(); - fixture.whenStable().then(() => { - expect(component.dockerTemplate.adapters).toBe(2); - - expect(component.virtualMachineForm.invalid).toBe(false); - expect(component.containerNameForm.invalid).toBe(false); - expect(component.networkAdaptersForm.invalid).toBe(false); - - let addButton = fixture.debugElement.nativeElement - .querySelector('.add-button'); - spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate)); - - addButton.click(); - - expect(mockedDockerService.addTemplate).toHaveBeenCalled(); - }); - }); - }); - }); + expect(mockedDockerService.addTemplate).toHaveBeenCalled(); }); + }); }); - }); - })); + }); + }); + }); + }); + })); }); diff --git a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts index daad9e05..f7d0529d 100644 --- a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts +++ b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts @@ -1,125 +1,128 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { DockerTemplate } from '../../../../models/templates/docker-template'; -import { DockerService } from '../../../../services/docker.service'; -import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; -import { DockerImage } from '../../../../models/docker/docker-image'; -import { ComputeService } from '../../../../services/compute.service'; import { Compute } from '../../../../models/compute'; - +import { DockerImage } from '../../../../models/docker/docker-image'; +import { Server } from '../../../../models/server'; +import { DockerTemplate } from '../../../../models/templates/docker-template'; +import { ComputeService } from '../../../../services/compute.service'; +import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; +import { DockerService } from '../../../../services/docker.service'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-add-docker-template', - templateUrl: './add-docker-template.component.html', - styleUrls: ['./add-docker-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-docker-template', + templateUrl: './add-docker-template.component.html', + styleUrls: ['./add-docker-template.component.scss', '../../preferences.component.scss'], }) export class AddDockerTemplateComponent implements OnInit { - server: Server; - dockerTemplate: DockerTemplate; - consoleTypes: string[] = []; - isRemoteComputerChosen: boolean = false; - dockerImages: DockerImage[] = []; - selectedImage: DockerImage; - newImageSelected: boolean = false; + server: Server; + dockerTemplate: DockerTemplate; + consoleTypes: string[] = []; + isRemoteComputerChosen: boolean = false; + dockerImages: DockerImage[] = []; + selectedImage: DockerImage; + newImageSelected: boolean = false; - virtualMachineForm: FormGroup; - containerNameForm: FormGroup; - networkAdaptersForm: FormGroup; + virtualMachineForm: FormGroup; + containerNameForm: FormGroup; + networkAdaptersForm: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private dockerService: DockerService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder, - private templateMocksService: TemplateMocksService, - private configurationService: DockerConfigurationService, - private computeService: ComputeService + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private dockerService: DockerService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder, + private templateMocksService: TemplateMocksService, + private configurationService: DockerConfigurationService, + private computeService: ComputeService + ) { + this.dockerTemplate = new DockerTemplate(); + + this.virtualMachineForm = this.formBuilder.group({ + filename: new FormControl(null, Validators.required), + }); + + this.containerNameForm = this.formBuilder.group({ + templateName: new FormControl(null, Validators.required), + }); + + this.networkAdaptersForm = this.formBuilder.group({ + adapters: new FormControl('1', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.consoleTypes = this.configurationService.getConsoleTypes(); + + this.templateMocksService.getDockerTemplate().subscribe((dockerTemplate: DockerTemplate) => { + this.dockerTemplate = dockerTemplate; + }); + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + + this.dockerService.getImages(server).subscribe((images) => { + this.dockerImages = images; + }); + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; + } + } + + setDiskImage(value: string) { + this.newImageSelected = value === 'newImage'; + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + } + + addTemplate() { + if ( + (!this.virtualMachineForm.invalid || (!this.newImageSelected && this.selectedImage)) && + !this.containerNameForm.invalid && + !this.networkAdaptersForm.invalid ) { - this.dockerTemplate = new DockerTemplate(); + this.dockerTemplate.template_id = uuid(); - this.virtualMachineForm = this.formBuilder.group({ - filename: new FormControl(null, Validators.required) - }); + if (this.newImageSelected) { + this.dockerTemplate.image = this.virtualMachineForm.get('filename').value; + } else { + this.dockerTemplate.image = this.selectedImage.image; + } - this.containerNameForm = this.formBuilder.group({ - templateName: new FormControl(null, Validators.required) - }); + this.dockerTemplate.name = this.containerNameForm.get('templateName').value; + this.dockerTemplate.adapters = +this.networkAdaptersForm.get('adapters').value; + this.dockerTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - this.networkAdaptersForm = this.formBuilder.group({ - adapters: new FormControl('1', Validators.required) - }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.consoleTypes = this.configurationService.getConsoleTypes(); - - this.templateMocksService.getDockerTemplate().subscribe((dockerTemplate: DockerTemplate) => { - this.dockerTemplate = dockerTemplate; - }) - - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - - this.dockerService.getImages(server).subscribe((images) => { - this.dockerImages = images; - }); - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - setDiskImage(value: string) { - this.newImageSelected = value === "newImage"; - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); - } - - addTemplate() { - if ((!this.virtualMachineForm.invalid || (!this.newImageSelected && this.selectedImage)) && !this.containerNameForm.invalid && !this.networkAdaptersForm.invalid) { - this.dockerTemplate.template_id = uuid(); - - if (this.newImageSelected) { - this.dockerTemplate.image = this.virtualMachineForm.get('filename').value; - } else { - this.dockerTemplate.image = this.selectedImage.image; - } - - this.dockerTemplate.name = this.containerNameForm.get('templateName').value; - this.dockerTemplate.adapters = +this.networkAdaptersForm.get('adapters').value; - this.dockerTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html index 6cea160e..3b2f0f93 100644 --- a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html +++ b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html @@ -1,24 +1,20 @@
-
-
-

Copy Docker container template

-
+
+
+

Copy Docker container template

-
-
-
- - - -
-
-
- - -
+
+
+
+
+ + + +
+
+ + +
+
diff --git a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts index e2e32b84..6e8c13c8 100644 --- a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts +++ b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts @@ -1,66 +1,64 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; +import { Server } from '../../../../models/server'; import { DockerTemplate } from '../../../../models/templates/docker-template'; import { DockerService } from '../../../../services/docker.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-copy-docker-template', - templateUrl: './copy-docker-template.component.html', - styleUrls: ['./copy-docker-template.component.scss', '../../preferences.component.scss'] + selector: 'app-copy-docker-template', + templateUrl: './copy-docker-template.component.html', + styleUrls: ['./copy-docker-template.component.scss', '../../preferences.component.scss'], }) export class CopyDockerTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - dockerTemplate: DockerTemplate; - templateNameForm: FormGroup; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private dockerService: DockerService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder - ) { - this.templateNameForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required) - }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.dockerService.getTemplate(this.server, template_id).subscribe((dockerTemplate: DockerTemplate) => { - this.dockerTemplate = dockerTemplate; - this.templateName = `Copy of ${this.dockerTemplate.name}`; - }) - - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); - } - - addTemplate() { - if (!this.templateNameForm.invalid) { - this.dockerTemplate.template_id = uuid(); - this.dockerTemplate.name = this.templateName; - - this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + server: Server; + templateName: string = ''; + dockerTemplate: DockerTemplate; + templateNameForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private dockerService: DockerService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.dockerService.getTemplate(this.server, template_id).subscribe((dockerTemplate: DockerTemplate) => { + this.dockerTemplate = dockerTemplate; + this.templateName = `Copy of ${this.dockerTemplate.name}`; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + } + + addTemplate() { + if (!this.templateNameForm.invalid) { + this.dockerTemplate.template_id = uuid(); + this.dockerTemplate.name = this.templateName; + + this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html index d603fb36..e36dccf0 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html @@ -1,96 +1,149 @@ -
-
-
-

Docker image configuration

-
+
+
+
+

Docker image configuration

-
- - - - - General settings - - -
- - - - - - - - - - {{category[0]}} - - - - - - -

- - - - - - - - - - {{type}} - - - - - Auto start console - - - - - {{resolution}} - - - - - - - - - -
-
Environment
- - - -
- - - - Advanced - - -
Extra hosts
- - - -
- - - - Usage - - - - - - -
-
- - -
+
+
+ + + + General settings + +
+ + + + + + + + + + {{ category[0] }} + + + + + + +

+ + + + + + + + + + {{ type }} + + + + + Auto start console + + + + + {{ resolution }} + + + + + + + + + +
+
Environment
+ + + +
+ + + Advanced + +
Extra hosts
+ + + +
+ + + Usage + + + + + +
+
+ +
+
- + diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts index 4b55dc92..84ff735d 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts @@ -1,83 +1,92 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { DockerTemplate } from '../../../../models/templates/docker-template'; -import { DockerTemplateDetailsComponent } from './docker-template-details.component'; -import { DockerService } from '../../../../services/docker.service'; import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; +import { DockerService } from '../../../../services/docker.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { DockerTemplateDetailsComponent } from './docker-template-details.component'; export class MockedDockerService { - public getTemplate(server: Server, template_id: string) { - return of({} as DockerTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as DockerTemplate); + } - public saveTemplate(server: Server, dockerTemplate: DockerTemplate) { - return of(dockerTemplate); - } + public saveTemplate(server: Server, dockerTemplate: DockerTemplate) { + return of(dockerTemplate); + } } describe('DockerTemplateDetailsComponent', () => { - let component: DockerTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: DockerTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedDockerService = new MockedDockerService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: DockerService, useValue: mockedDockerService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: DockerConfigurationService, useClass: DockerConfigurationService } - ], - declarations: [ - DockerTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedDockerService = new MockedDockerService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(DockerTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: DockerService, useValue: mockedDockerService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: DockerConfigurationService, useClass: DockerConfigurationService }, + ], + declarations: [DockerTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DockerTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedDockerService, 'saveTemplate').and.returnValue(of({} as DockerTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['adapter'].setValue(1); - component.generalSettingsForm.controls['symbol'].setValue('symbol path'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedDockerService, 'saveTemplate').and.returnValue(of({} as DockerTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['adapter'].setValue(1); + component.generalSettingsForm.controls['symbol'].setValue('symbol path'); - expect(mockedDockerService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedDockerService.saveTemplate).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts index 18ffaa61..3c57a696 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts @@ -1,89 +1,88 @@ -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; +import { Server } from '../../../../models/server'; import { DockerTemplate } from '../../../../models/templates/docker-template'; -import { DockerService } from '../../../../services/docker.service'; import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { DockerService } from '../../../../services/docker.service'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-docker-template-details', - templateUrl: './docker-template-details.component.html', - styleUrls: ['./docker-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-docker-template-details', + templateUrl: './docker-template-details.component.html', + styleUrls: ['./docker-template-details.component.scss', '../../preferences.component.scss'], }) export class DockerTemplateDetailsComponent implements OnInit { - server: Server; - dockerTemplate: DockerTemplate; + server: Server; + dockerTemplate: DockerTemplate; - isSymbolSelectionOpened: boolean = false; + isSymbolSelectionOpened: boolean = false; - consoleTypes: string[] = []; - consoleResolutions: string[] = []; - categories = []; - adapters: CustomAdapter[] = []; - displayedColumns: string[] = ['adapter_number', 'port_name']; + consoleTypes: string[] = []; + consoleResolutions: string[] = []; + categories = []; + adapters: CustomAdapter[] = []; + displayedColumns: string[] = ['adapter_number', 'port_name']; - generalSettingsForm: FormGroup; + generalSettingsForm: FormGroup; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private dockerService: DockerService, - private toasterService: ToasterService, - private configurationService: DockerConfigurationService, - private formBuilder: FormBuilder, - private router: Router - ){ - this.generalSettingsForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - adapter: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) - }); + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private dockerService: DockerService, + private toasterService: ToasterService, + private configurationService: DockerConfigurationService, + private formBuilder: FormBuilder, + private router: Router + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + adapter: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.dockerService.getTemplate(this.server, template_id).subscribe((dockerTemplate: DockerTemplate) => { + this.dockerTemplate = dockerTemplate; + }); + }); + } + + getConfiguration() { + this.consoleTypes = this.configurationService.getConsoleTypes(); + this.categories = this.configurationService.getCategories(); + this.consoleResolutions = this.configurationService.getConsoleResolutions(); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + } + + onSave() { + if (this.generalSettingsForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.dockerService.saveTemplate(this.server, this.dockerTemplate).subscribe((savedTemplate: DockerTemplate) => { + this.toasterService.success('Changes saved'); + }); } + } - ngOnInit(){ - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.getConfiguration(); - this.dockerService.getTemplate(this.server, template_id).subscribe((dockerTemplate: DockerTemplate) => { - this.dockerTemplate = dockerTemplate; - }); - }); - } + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - getConfiguration(){ - this.consoleTypes = this.configurationService.getConsoleTypes(); - this.categories = this.configurationService.getCategories(); - this.consoleResolutions = this.configurationService.getConsoleResolutions(); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); - } - - onSave(){ - if (this.generalSettingsForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.dockerService.saveTemplate(this.server, this.dockerTemplate).subscribe((savedTemplate: DockerTemplate) => { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.dockerTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.dockerTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/docker/docker-templates/docker-templates.component.html b/src/app/components/preferences/docker/docker-templates/docker-templates.component.html index b732ad1e..72227b93 100644 --- a/src/app/components/preferences/docker/docker-templates/docker-templates.component.html +++ b/src/app/components/preferences/docker/docker-templates/docker-templates.component.html @@ -1,35 +1,49 @@
-
-
-

Docker container templates

- - -
+
+
+

Docker container templates

+ +
- -
-
- -
- {{template.name}} - - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + + +
+
+
- - + diff --git a/src/app/components/preferences/docker/docker-templates/docker-templates.component.spec.ts b/src/app/components/preferences/docker/docker-templates/docker-templates.component.spec.ts index 245aaf08..7a89634b 100644 --- a/src/app/components/preferences/docker/docker-templates/docker-templates.component.spec.ts +++ b/src/app/components/preferences/docker/docker-templates/docker-templates.component.spec.ts @@ -1,58 +1,64 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { DockerTemplate } from '../../../../models/templates/docker-template'; -import { DockerTemplatesComponent } from './docker-templates.component'; import { DockerService } from '../../../../services/docker.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { DockerTemplatesComponent } from './docker-templates.component'; export class MockedDockerService { - public getTemplates(server: Server) { - return of([{} as DockerTemplate]); - } + public getTemplates(server: Server) { + return of([{} as DockerTemplate]); + } } describe('DockerTemplatesComponent', () => { - let component: DockerTemplatesComponent; - let fixture: ComponentFixture; + let component: DockerTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedDockerService = new MockedDockerService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: DockerService, useValue: mockedDockerService } - ], - declarations: [ - DockerTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedDockerService = new MockedDockerService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(DockerTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: DockerService, useValue: mockedDockerService }, + ], + declarations: [DockerTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DockerTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts b/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts index 1fe7f1c6..e44688a0 100644 --- a/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts +++ b/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts @@ -1,52 +1,59 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; +import { Server } from '../../../../models/server'; import { DockerTemplate } from '../../../../models/templates/docker-template'; import { DockerService } from '../../../../services/docker.service'; - +import { ServerService } from '../../../../services/server.service'; +import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ - selector: 'app-docker-templates', - templateUrl: './docker-templates.component.html', - styleUrls: ['./docker-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-docker-templates', + templateUrl: './docker-templates.component.html', + styleUrls: ['./docker-templates.component.scss', '../../preferences.component.scss'], }) export class DockerTemplatesComponent implements OnInit { - server: Server; - dockerTemplates: DockerTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + dockerTemplates: DockerTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private dockerService: DockerService, - private router: Router - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private dockerService: DockerService, + private router: Router + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.dockerService.getTemplates(this.server).subscribe((dockerTemplates: DockerTemplate[]) => { - this.dockerTemplates = dockerTemplates.filter((elem) => elem.template_type === 'docker' && !elem.builtin); - }); - } + getTemplates() { + this.dockerService.getTemplates(this.server).subscribe((dockerTemplates: DockerTemplate[]) => { + this.dockerTemplates = dockerTemplates.filter((elem) => elem.template_type === 'docker' && !elem.builtin); + }); + } - deleteTemplate(template: DockerTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: DockerTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } - copyTemplate(template: DockerTemplate) { - this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates', template.template_id, 'copy']); - } + copyTemplate(template: DockerTemplate) { + this.router.navigate([ + '/server', + this.server.id, + 'preferences', + 'docker', + 'templates', + template.template_id, + 'copy', + ]); + } } diff --git a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html index 6a4b913a..1b41b969 100644 --- a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html +++ b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.html @@ -1,99 +1,109 @@
-
-
-

New IOS router template

-
+
+
+

New IOS router template

-
-
- - - - Run this IOS router locally - Run this IOS router on the GNS3 VM - - +
+
+
+ + + + Run this IOS router locally + Run this IOS router on the GNS3 VM + + - - - or create from existing one -
- - - - {{image.filename}} - - - -
-
+ + + or create from + existing one +
+ + + + {{ image.filename }} + + + +
+
- -
- - - - - - - {{platform}} - - - - - - - {{chassis}} - - - -
- - This is an EtherSwitch router - -
+ +
+ + + + + + + {{ platform }} + + + + + + + {{ chassis }} + + + +
+ + This is an EtherSwitch router + +
- -
- - - MB - - - Check for minimum and maximum RAM requirement - -
-
+ +
+ + + MB + + + Check for minimum and maximum RAM requirement + +
+
- - -
-
- - - {{option}} - - -
-
-
+
+
+ + + {{ option }} + + +
+
+ - -
-
- - - {{option}} - - -
-
-
+ +
+
+ + + {{ option }} + + +
+
+
- - - - - -
-
-
- - -
+ + + + + +
+
+ + +
+
diff --git a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.scss b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.scss index 0f602793..f4d855b4 100644 --- a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.scss +++ b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.scss @@ -1,3 +1,3 @@ .non-visible { - display: none; + display: none; } diff --git a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.spec.ts b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.spec.ts index 45df3039..98db342b 100644 --- a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.spec.ts +++ b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.spec.ts @@ -1,4 +1,7 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -9,136 +12,133 @@ import { MatSelectModule } from '@angular/material/select'; import { MatStepperModule } from '@angular/material/stepper'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; +import { IosTemplate } from '../../../../models/templates/ios-template'; +import { IosConfigurationService } from '../../../../services/ios-configuration.service'; +import { IosService } from '../../../../services/ios.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { IosTemplate } from '../../../../models/templates/ios-template'; import { AddIosTemplateComponent } from './add-ios-template.component'; -import { IosService } from '../../../../services/ios.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { IosConfigurationService } from '../../../../services/ios-configuration.service'; export class MockedIosService { - public addTemplate(server: Server, iosTemplate: IosTemplate) { - return of(iosTemplate); - } + public addTemplate(server: Server, iosTemplate: IosTemplate) { + return of(iosTemplate); + } } //Tests disabled due to instability xdescribe('AddIosTemplateComponent', () => { - let component: AddIosTemplateComponent; - let fixture: ComponentFixture; + let component: AddIosTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedIosService = new MockedIosService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - MatStepperModule, - FormsModule, - MatTableModule, - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - ReactiveFormsModule, - MatSelectModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/dynamips/templates', component: AddIosTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: IosService, useValue: mockedIosService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: TemplateMocksService, useClass: TemplateMocksService }, - { provide: IosConfigurationService, useClass: IosConfigurationService } - ], - declarations: [ - AddIosTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedIosService = new MockedIosService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(AddIosTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatStepperModule, + FormsModule, + MatTableModule, + MatAutocompleteModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule, + MatSelectModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/dynamips/templates', component: AddIosTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: IosService, useValue: mockedIosService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + { provide: IosConfigurationService, useClass: IosConfigurationService }, + ], + declarations: [AddIosTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AddIosTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call add template', () => { - spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); - component.iosImageForm.controls['imageName'].setValue('image name'); - component.iosNameForm.controls['templateName'].setValue('template name'); - component.iosNameForm.controls['platform'].setValue('platform'); - component.iosNameForm.controls['chassis'].setValue('chassis'); - component.iosMemoryForm.controls['memory'].setValue(0); - component.server = {id: 1} as Server; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call add template', () => { + spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); + component.iosImageForm.controls['imageName'].setValue('image name'); + component.iosNameForm.controls['templateName'].setValue('template name'); + component.iosNameForm.controls['platform'].setValue('platform'); + component.iosNameForm.controls['chassis'].setValue('chassis'); + component.iosMemoryForm.controls['memory'].setValue(0); + component.server = { id: 1 } as Server; - expect(mockedIosService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when template name is not defined', () => { - spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); - component.iosImageForm.controls['imageName'].setValue('image name'); - component.iosNameForm.controls['templateName'].setValue(''); - component.iosNameForm.controls['platform'].setValue('platform'); - component.iosNameForm.controls['chassis'].setValue('chassis'); - component.iosMemoryForm.controls['memory'].setValue(0); - component.server = {id: 1} as Server; + expect(mockedIosService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when template name is not defined', () => { + spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); + component.iosImageForm.controls['imageName'].setValue('image name'); + component.iosNameForm.controls['templateName'].setValue(''); + component.iosNameForm.controls['platform'].setValue('platform'); + component.iosNameForm.controls['chassis'].setValue('chassis'); + component.iosMemoryForm.controls['memory'].setValue(0); + component.server = { id: 1 } as Server; - expect(mockedIosService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when image name is not defined', () => { - spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); - component.iosNameForm.controls['templateName'].setValue('template name'); - component.iosNameForm.controls['platform'].setValue('platform'); - component.iosNameForm.controls['chassis'].setValue('chassis'); - component.iosMemoryForm.controls['memory'].setValue(0); - component.server = {id: 1} as Server; + expect(mockedIosService.addTemplate).not.toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when image name is not defined', () => { + spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); + component.iosNameForm.controls['templateName'].setValue('template name'); + component.iosNameForm.controls['platform'].setValue('platform'); + component.iosNameForm.controls['chassis'].setValue('chassis'); + component.iosMemoryForm.controls['memory'].setValue(0); + component.server = { id: 1 } as Server; - expect(mockedIosService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when memory is not defined', () => { - spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); - component.iosImageForm.controls['imageName'].setValue('image name'); - component.iosNameForm.controls['templateName'].setValue('template name'); - component.iosNameForm.controls['platform'].setValue('platform'); - component.iosNameForm.controls['chassis'].setValue('chassis'); - component.server = {id: 1} as Server; + expect(mockedIosService.addTemplate).not.toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when memory is not defined', () => { + spyOn(mockedIosService, 'addTemplate').and.returnValue(of({} as IosTemplate)); + component.iosImageForm.controls['imageName'].setValue('image name'); + component.iosNameForm.controls['templateName'].setValue('template name'); + component.iosNameForm.controls['platform'].setValue('platform'); + component.iosNameForm.controls['chassis'].setValue('chassis'); + component.server = { id: 1 } as Server; - expect(mockedIosService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedIosService.addTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts index 5447f498..f420859a 100644 --- a/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts +++ b/src/app/components/preferences/dynamips/add-ios-template/add-ios-template.component.ts @@ -1,256 +1,265 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; -import { IosTemplate } from '../../../../models/templates/ios-template'; -import { IosService } from '../../../../services/ios.service'; +import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { IosConfigurationService } from '../../../../services/ios-configuration.service'; -import { IosImage } from '../../../../models/images/ios-image'; -import { FileUploader, FileItem, ParsedResponseHeaders } from 'ng2-file-upload'; -import { ServerResponse } from '../../../../models/serverResponse'; -import { ComputeService } from '../../../../services/compute.service'; import { Compute } from '../../../../models/compute'; +import { IosImage } from '../../../../models/images/ios-image'; +import { Server } from '../../../../models/server'; +import { IosTemplate } from '../../../../models/templates/ios-template'; +import { ComputeService } from '../../../../services/compute.service'; +import { IosConfigurationService } from '../../../../services/ios-configuration.service'; +import { IosService } from '../../../../services/ios.service'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-add-ios-template', - templateUrl: './add-ios-template.component.html', - styleUrls: ['./add-ios-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-ios-template', + templateUrl: './add-ios-template.component.html', + styleUrls: ['./add-ios-template.component.scss', '../../preferences.component.scss'], }) export class AddIosTemplateComponent implements OnInit { - server: Server; - iosTemplate: IosTemplate; - isEtherSwitchRouter: boolean = false; + server: Server; + iosTemplate: IosTemplate; + isEtherSwitchRouter: boolean = false; - iosImageForm: FormGroup; - iosNameForm: FormGroup; - iosMemoryForm: FormGroup; - selectedPlatform: string; + iosImageForm: FormGroup; + iosNameForm: FormGroup; + iosMemoryForm: FormGroup; + selectedPlatform: string; - networkAdaptersForTemplate: string[] = []; - networkModulesForTemplate: string[] = []; + networkAdaptersForTemplate: string[] = []; + networkModulesForTemplate: string[] = []; - iosImages: IosImage[] = []; - platforms: string[] = []; - platformsWithEtherSwitchRouterOption = {}; - platformsWithChassis = {}; - chassis = {}; - defaultRam = {}; - defaultNvram = {}; - networkAdapters = {}; - networkAdaptersForPlatform = {}; - networkModules = {}; + iosImages: IosImage[] = []; + platforms: string[] = []; + platformsWithEtherSwitchRouterOption = {}; + platformsWithChassis = {}; + chassis = {}; + defaultRam = {}; + defaultNvram = {}; + networkAdapters = {}; + networkAdaptersForPlatform = {}; + networkModules = {}; - ciscoUrl: string = "https://cfn.cloudapps.cisco.com/ITDIT/CFN/jsp/SearchBySoftware.jsp"; - uploader: FileUploader; + ciscoUrl: string = 'https://cfn.cloudapps.cisco.com/ITDIT/CFN/jsp/SearchBySoftware.jsp'; + uploader: FileUploader; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iosService: IosService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private router: Router, - private templateMocksService: TemplateMocksService, - private iosConfigurationService: IosConfigurationService, - private computeService: ComputeService + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iosService: IosService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private router: Router, + private templateMocksService: TemplateMocksService, + private iosConfigurationService: IosConfigurationService, + private computeService: ComputeService + ) { + this.iosTemplate = new IosTemplate(); + + this.iosImageForm = this.formBuilder.group({ + imageName: new FormControl(null, [Validators.required]), + }); + + this.iosNameForm = this.formBuilder.group({ + templateName: new FormControl(null, [Validators.required]), + platform: new FormControl(null, [Validators.required]), + chassis: new FormControl(null, [Validators.required]), + }); + + this.iosMemoryForm = this.formBuilder.group({ + memory: new FormControl(null, [Validators.required]), + }); + } + + ngOnInit() { + this.uploader = new FileUploader({}); + this.uploader.onAfterAddingFile = (file) => { + file.withCredentials = false; + }; + this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { + this.toasterService.error('An error occured: ' + response); + }; + this.uploader.onSuccessItem = ( + item: FileItem, + response: string, + status: number, + headers: ParsedResponseHeaders + ) => { + this.getImages(); + this.toasterService.success('Image uploaded'); + }; + + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getImages(); + + this.templateMocksService.getIosTemplate().subscribe((iosTemplate: IosTemplate) => { + this.iosTemplate = iosTemplate; + + this.networkModules = this.iosConfigurationService.getNetworkModules(); + this.networkAdaptersForPlatform = this.iosConfigurationService.getNetworkAdaptersForPlatform(); + this.networkAdapters = this.iosConfigurationService.getNetworkAdapters(); + this.platforms = this.iosConfigurationService.getAvailablePlatforms(); + this.platformsWithEtherSwitchRouterOption = this.iosConfigurationService.getPlatformsWithEtherSwitchRouterOption(); + this.platformsWithChassis = this.iosConfigurationService.getPlatformsWithChassis(); + this.chassis = this.iosConfigurationService.getChassis(); + this.defaultRam = this.iosConfigurationService.getDefaultRamSettings(); + }); + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; + } + } + + getImages() { + this.iosService.getImages(this.server).subscribe((images: IosImage[]) => { + this.iosImages = images; + }); + } + + addImage(event): void { + let name = event.target.files[0].name.split('-')[0]; + this.iosNameForm.controls['templateName'].setValue(name); + let fileName = event.target.files[0].name; + + const url = this.iosService.getImagePath(this.server, fileName); + this.uploader.queue.forEach((elem) => (elem.url = url)); + + const itemToUpload = this.uploader.queue[0]; + (itemToUpload as any).options.disableMultipart = true; + + this.uploader.uploadItem(itemToUpload); + } + + addTemplate() { + if ( + !this.iosImageForm.invalid && + !this.iosMemoryForm.invalid && + this.iosNameForm.get('templateName').value && + this.iosNameForm.get('platform').value ) { - this.iosTemplate = new IosTemplate(); + this.iosTemplate.template_id = uuid(); + this.iosTemplate.image = this.iosImageForm.get('imageName').value; + this.iosTemplate.name = this.iosNameForm.get('templateName').value; + this.iosTemplate.platform = this.iosNameForm.get('platform').value; - this.iosImageForm = this.formBuilder.group({ - imageName: new FormControl(null, [Validators.required]) - }); + if (this.chassis[this.iosNameForm.get('platform').value]) + this.iosTemplate.chassis = this.iosNameForm.get('chassis').value; + this.iosTemplate.ram = this.iosMemoryForm.get('memory').value; - this.iosNameForm = this.formBuilder.group({ - templateName: new FormControl(null, [Validators.required]), - platform: new FormControl(null, [Validators.required]), - chassis: new FormControl(null, [Validators.required]) - }); + if (this.isEtherSwitchRouter) { + this.iosTemplate.symbol = ':/symbols/multilayer_switch.svg'; + this.iosTemplate.category = 'switch'; + } - this.iosMemoryForm = this.formBuilder.group({ - memory: new FormControl(null, [Validators.required]) - }); + if (this.networkAdaptersForTemplate.length > 0) this.completeAdaptersData(); + if (this.networkModulesForTemplate.length > 0) this.completeModulesData(); + + this.iosTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; + + this.iosService.addTemplate(this.server, this.iosTemplate).subscribe((template: IosTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } - ngOnInit() { - this.uploader = new FileUploader({}); - this.uploader.onAfterAddingFile = file => { - file.withCredentials = false; - }; - this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { - this.toasterService.error('An error occured: ' + response); - }; - this.uploader.onSuccessItem = ( - item: FileItem, - response: string, - status: number, - headers: ParsedResponseHeaders - ) => { - this.getImages(); - this.toasterService.success('Image uploaded'); - }; - - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.getImages(); - - this.templateMocksService.getIosTemplate().subscribe((iosTemplate: IosTemplate) => { - this.iosTemplate = iosTemplate; - - this.networkModules = this.iosConfigurationService.getNetworkModules(); - this.networkAdaptersForPlatform = this.iosConfigurationService.getNetworkAdaptersForPlatform(); - this.networkAdapters = this.iosConfigurationService.getNetworkAdapters(); - this.platforms = this.iosConfigurationService.getAvailablePlatforms(); - this.platformsWithEtherSwitchRouterOption = this.iosConfigurationService.getPlatformsWithEtherSwitchRouterOption(); - this.platformsWithChassis = this.iosConfigurationService.getPlatformsWithChassis(); - this.chassis = this.iosConfigurationService.getChassis(); - this.defaultRam = this.iosConfigurationService.getDefaultRamSettings(); - }); - - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; + completeAdaptersData() { + if (this.chassis[this.iosTemplate.platform]) { + if (Object.keys(this.networkAdapters[this.iosTemplate.chassis])) { + for (let i = 0; i < Object.keys(this.networkAdapters[this.iosTemplate.chassis]).length; i++) { + if (!this.networkAdaptersForTemplate[i]) this.networkAdaptersForTemplate[i] = ''; } - } - - getImages() { - this.iosService.getImages(this.server).subscribe((images: IosImage[]) => { - this.iosImages = images; - }); - } - - addImage(event): void { - let name = event.target.files[0].name.split('-')[0]; - this.iosNameForm.controls['templateName'].setValue(name); - let fileName = event.target.files[0].name; - - const url = this.iosService.getImagePath(this.server, fileName); - this.uploader.queue.forEach(elem => (elem.url = url)); - - const itemToUpload = this.uploader.queue[0]; - (itemToUpload as any).options.disableMultipart = true; - - this.uploader.uploadItem(itemToUpload); - } - - addTemplate() { - if (!this.iosImageForm.invalid && !this.iosMemoryForm.invalid && this.iosNameForm.get('templateName').value && this.iosNameForm.get('platform').value) { - this.iosTemplate.template_id = uuid(); - this.iosTemplate.image = this.iosImageForm.get("imageName").value; - this.iosTemplate.name = this.iosNameForm.get('templateName').value; - this.iosTemplate.platform = this.iosNameForm.get('platform').value; - - if (this.chassis[this.iosNameForm.get('platform').value]) this.iosTemplate.chassis = this.iosNameForm.get('chassis').value; - this.iosTemplate.ram = this.iosMemoryForm.get('memory').value; - - if (this.isEtherSwitchRouter) { - this.iosTemplate.symbol = ":/symbols/multilayer_switch.svg"; - this.iosTemplate.category = "switch"; - } - - if (this.networkAdaptersForTemplate.length>0) this.completeAdaptersData(); - if (this.networkModulesForTemplate.length>0) this.completeModulesData(); - - this.iosTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - this.iosService.addTemplate(this.server, this.iosTemplate).subscribe((template: IosTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); + } + } else { + if (this.networkAdaptersForPlatform[this.iosNameForm.get('platform').value]) { + for ( + let i = 0; + i < Object.keys(this.networkAdaptersForPlatform[this.iosNameForm.get('platform').value]).length; + i++ + ) { + if (!this.networkAdaptersForTemplate[i]) this.networkAdaptersForTemplate[i] = ''; } + } } - completeAdaptersData() { - if (this.chassis[this.iosTemplate.platform]) { - if(Object.keys(this.networkAdapters[this.iosTemplate.chassis])){ - for(let i=0; i -
-
-

Copy IOS router template

-
+
+
+

Copy IOS router template

-
- -
- - - -
-
-
- - -
+
+
+ +
+ + + +
+
+
+ +
+
diff --git a/src/app/components/preferences/dynamips/copy-ios-template/copy-ios-template.component.ts b/src/app/components/preferences/dynamips/copy-ios-template/copy-ios-template.component.ts index f400eb41..eb1dd44d 100644 --- a/src/app/components/preferences/dynamips/copy-ios-template/copy-ios-template.component.ts +++ b/src/app/components/preferences/dynamips/copy-ios-template/copy-ios-template.component.ts @@ -1,66 +1,64 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; import { v4 as uuid } from 'uuid'; +import { Server } from '../../../../models/server'; import { IosTemplate } from '../../../../models/templates/ios-template'; import { IosService } from '../../../../services/ios.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-copy-ios-template', - templateUrl: './copy-ios-template.component.html', - styleUrls: ['./copy-ios-template.component.scss', '../../preferences.component.scss'] + selector: 'app-copy-ios-template', + templateUrl: './copy-ios-template.component.html', + styleUrls: ['./copy-ios-template.component.scss', '../../preferences.component.scss'], }) export class CopyIosTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - iosTemplate: IosTemplate; - formGroup: FormGroup; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iosService: IosService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder - ) { - this.formGroup = this.formBuilder.group({ - templateName: new FormControl('', Validators.required) - }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.iosService.getTemplate(this.server, template_id).subscribe((iosTemplate: IosTemplate) => { - this.iosTemplate = iosTemplate; - this.templateName = `Copy of ${this.iosTemplate.name}`; - }) - - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'dynamips', 'templates']); - } - - addTemplate() { - if (!this.formGroup.invalid) { - this.iosTemplate.template_id = uuid(); - this.iosTemplate.name = this.templateName; - - this.iosService.addTemplate(this.server, this.iosTemplate).subscribe((template: IosTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + server: Server; + templateName: string = ''; + iosTemplate: IosTemplate; + formGroup: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iosService: IosService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.formGroup = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.iosService.getTemplate(this.server, template_id).subscribe((iosTemplate: IosTemplate) => { + this.iosTemplate = iosTemplate; + this.templateName = `Copy of ${this.iosTemplate.name}`; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'dynamips', 'templates']); + } + + addTemplate() { + if (!this.formGroup.invalid) { + this.iosTemplate.template_id = uuid(); + this.iosTemplate.name = this.templateName; + + this.iosService.addTemplate(this.server, this.iosTemplate).subscribe((template: IosTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.html b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.html index 2864366e..e1a11bb7 100644 --- a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.html +++ b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.html @@ -1,12 +1,12 @@
-
-
-

Dynamips preferences

-
-
-
- - - +
+
+

Dynamips preferences

+
+
+ + + +
diff --git a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.scss b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.scss index 93342be4..9800a50e 100644 --- a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.scss +++ b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.scss @@ -1,8 +1,8 @@ .top-button { - height: 36px; - margin-top: 22px + height: 36px; + margin-top: 22px; } .form-field { - width: 100%; + width: 100%; } diff --git a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.spec.ts b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.spec.ts index 1a191bf6..1cf24f9d 100644 --- a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.spec.ts +++ b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.spec.ts @@ -1,64 +1,72 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { HttpClientModule } from '@angular/common/http'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { RouterTestingModule } from '@angular/router/testing'; import { ServerSettingsService } from '../../../../services/server-settings.service'; -import { HttpClientModule } from '@angular/common/http'; import { MockedServerSettingsService } from '../../../../services/server-settings.service.spec'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; import { DynamipsPreferencesComponent } from './dynamips-preferences.component'; describe('DynamipsPreferencesComponent', () => { - let component: DynamipsPreferencesComponent; - let fixture: ComponentFixture; + let component: DynamipsPreferencesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let activatedRoute = new MockedActivatedRoute().get(); - let mockedServerSettingsService = new MockedServerSettingsService(); - let mockedToasterService = new MockedToasterService(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [HttpClientModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: ServerSettingsService, useValue: mockedServerSettingsService }, - { provide: ToasterService, useValue: mockedToasterService } - ], - declarations: [ - DynamipsPreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let activatedRoute = new MockedActivatedRoute().get(); + let mockedServerSettingsService = new MockedServerSettingsService(); + let mockedToasterService = new MockedToasterService(); - beforeEach(() => { - fixture = TestBed.createComponent(DynamipsPreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: ServerSettingsService, useValue: mockedServerSettingsService }, + { provide: ToasterService, useValue: mockedToasterService }, + ], + declarations: [DynamipsPreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(DynamipsPreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should clear path when restore defaults called', () => { - component.dynamipsPath = 'Non empty'; - component.restoreDefaults(); + it('should create', () => { + expect(component).toBeTruthy(); + }); - expect(component.dynamipsPath).toBe(''); - }); + it('should clear path when restore defaults called', () => { + component.dynamipsPath = 'Non empty'; + component.restoreDefaults(); + + expect(component.dynamipsPath).toBe(''); + }); }); diff --git a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.ts b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.ts index b6c92fdb..a8126286 100644 --- a/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.ts +++ b/src/app/components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component.ts @@ -1,33 +1,32 @@ -import { Component, OnInit } from "@angular/core"; -import { ServerSettingsService } from '../../../../services/server-settings.service'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; +import { ServerSettingsService } from '../../../../services/server-settings.service'; import { ServerService } from '../../../../services/server.service'; - @Component({ - selector: 'app-dynamips-preferences', - templateUrl: './dynamips-preferences.component.html', - styleUrls: ['./dynamips-preferences.component.scss'] + selector: 'app-dynamips-preferences', + templateUrl: './dynamips-preferences.component.html', + styleUrls: ['./dynamips-preferences.component.scss'], }) export class DynamipsPreferencesComponent implements OnInit { - server: Server; - dynamipsPath: string; + server: Server; + dynamipsPath: string; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private serverSettingsService: ServerSettingsService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private serverSettingsService: ServerSettingsService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + }); + } - restoreDefaults() { - this.dynamipsPath = ''; - } + restoreDefaults() { + this.dynamipsPath = ''; + } } diff --git a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html index b4470c3f..8c3f8c83 100644 --- a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html +++ b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.html @@ -1,200 +1,288 @@
-
-
-

Dynamips IOS Router configuration

-
+
+
+

Dynamips IOS Router configuration

-
- - - - - General settings - - -
- - - - - - - Platform - {{iosTemplate.platform}}

- Chassis - {{iosTemplate.chassis}}

- - - -

- - - - {{category[0]}} - - - - - - - - - - - - -
- - - - {{type}} - - - - - Auto start console - -
- - - - Memories and disks - - -
- - - MB - - - - MB - - - - - - - - - - -
- - Automatically delete NVRAM and disk files - -
- - - - Slots - - -
Adapters
-
-
- - - {{option}} - - -
-
-
-
- - - {{option}} - - -
-


-
WICs
-
- - - {{option}} - - -
-
- - - {{option}} - - -
-
- - - {{option}} - - -
-
- - - - Advanced - - -
- - - - - - - - - - - - - - - - - - -
- - Enable mmap support -

- - Enable sparse memory supoport - -
- - - - Usage - - - - - - -
-
- - +
+
+ + + + General settings + +
+ + + + + + + Platform - {{ iosTemplate.platform }}

+ Chassis - {{ iosTemplate.chassis }}

+ + + +

+ + + + {{ category[0] }} + + + + + + + + + + + + +
+ + + + {{ type }} + + + + Auto start console +
+ + + Memories and disks + +
+ + + MB + + + + MB + + + + + + + + + + +
+ + Automatically delete NVRAM and disk files + +
+ + + Slots + +
Adapters
+
+
+ + + {{ option }} + + +
+
+
+ + + {{ option }} + + +
+
+

+
WICs
+
+ + + {{ option }} + + +
+
+ + + {{ option }} + + +
+
+ + + {{ option }} + + +
+
+ + + Advanced + +
+ + + + + + + + + + + + + + + + + + +
+ Enable mmap support

+ Enable sparse memory supoport +
+ + + Usage + + + + + +
+
+ +
+
- + diff --git a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts index 0670d519..e7413abd 100644 --- a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts +++ b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.spec.ts @@ -1,93 +1,102 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { IosTemplate } from '../../../../models/templates/ios-template'; -import { IosTemplateDetailsComponent } from './ios-template-details.component'; -import { IosService } from '../../../../services/ios.service'; import { IosConfigurationService } from '../../../../services/ios-configuration.service'; +import { IosService } from '../../../../services/ios.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { IosTemplateDetailsComponent } from './ios-template-details.component'; export class MockedIosService { - public getTemplate(server: Server, template_id: string) { - return of({} as IosTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as IosTemplate); + } - public saveTemplate(server: Server, iosTemplate: IosTemplate) { - return of(iosTemplate); - } + public saveTemplate(server: Server, iosTemplate: IosTemplate) { + return of(iosTemplate); + } } describe('IosTemplateDetailsComponent', () => { - let component: IosTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: IosTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedIosService = new MockedIosService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: IosService, useValue: mockedIosService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: IosConfigurationService, useClass: IosConfigurationService } - ], - declarations: [ - IosTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedIosService = new MockedIosService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(IosTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: IosService, useValue: mockedIosService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: IosConfigurationService, useClass: IosConfigurationService }, + ], + declarations: [IosTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IosTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedIosService, 'saveTemplate').and.returnValue(of({} as IosTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.generalSettingsForm.controls['path'].setValue('path'); - component.generalSettingsForm.controls['initialConfig'].setValue('txt'); - component.memoryForm.controls['ram'].setValue('0'); - component.memoryForm.controls['nvram'].setValue('0'); - component.memoryForm.controls['iomemory'].setValue('0'); - component.memoryForm.controls['disk0'].setValue('0'); - component.memoryForm.controls['disk1'].setValue('0'); - component.advancedForm.controls['systemId'].setValue('0'); - component.advancedForm.controls['idlemax'].setValue('0'); - component.advancedForm.controls['idlesleep'].setValue('0'); - component.advancedForm.controls['execarea'].setValue('0'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedIosService, 'saveTemplate').and.returnValue(of({} as IosTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['path'].setValue('path'); + component.generalSettingsForm.controls['initialConfig'].setValue('txt'); + component.memoryForm.controls['ram'].setValue('0'); + component.memoryForm.controls['nvram'].setValue('0'); + component.memoryForm.controls['iomemory'].setValue('0'); + component.memoryForm.controls['disk0'].setValue('0'); + component.memoryForm.controls['disk1'].setValue('0'); + component.advancedForm.controls['systemId'].setValue('0'); + component.advancedForm.controls['idlemax'].setValue('0'); + component.advancedForm.controls['idlesleep'].setValue('0'); + component.advancedForm.controls['execarea'].setValue('0'); - expect(mockedIosService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedIosService.saveTemplate).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.ts b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.ts index 22be26da..750b9231 100644 --- a/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.ts +++ b/src/app/components/preferences/dynamips/ios-template-details/ios-template-details.component.ts @@ -1,145 +1,144 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; import { IosTemplate } from '../../../../models/templates/ios-template'; -import { IosService } from '../../../../services/ios.service'; import { IosConfigurationService } from '../../../../services/ios-configuration.service'; - +import { IosService } from '../../../../services/ios.service'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-ios-template-details', - templateUrl: './ios-template-details.component.html', - styleUrls: ['./ios-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-ios-template-details', + templateUrl: './ios-template-details.component.html', + styleUrls: ['./ios-template-details.component.scss', '../../preferences.component.scss'], }) export class IosTemplateDetailsComponent implements OnInit { - server: Server; - iosTemplate: IosTemplate; + server: Server; + iosTemplate: IosTemplate; - isSymbolSelectionOpened: boolean = false; + isSymbolSelectionOpened: boolean = false; - networkAdaptersForTemplate: string[] = []; - platforms: string[] = []; - consoleTypes: string[] = []; - platformsWithEtherSwitchRouterOption = {}; - platformsWithChassis = {}; - chassis = {}; - defaultRam = {}; - defaultNvram = {}; - networkAdapters = {}; - networkAdaptersForPlatform = {}; - networkModules = {}; + networkAdaptersForTemplate: string[] = []; + platforms: string[] = []; + consoleTypes: string[] = []; + platformsWithEtherSwitchRouterOption = {}; + platformsWithChassis = {}; + chassis = {}; + defaultRam = {}; + defaultNvram = {}; + networkAdapters = {}; + networkAdaptersForPlatform = {}; + networkModules = {}; - generalSettingsForm: FormGroup; - memoryForm: FormGroup; - advancedForm: FormGroup; + generalSettingsForm: FormGroup; + memoryForm: FormGroup; + advancedForm: FormGroup; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iosService: IosService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private iosConfigurationService: IosConfigurationService, - private router: Router - ) { - this.generalSettingsForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required), - path: new FormControl('', Validators.required), - initialConfig: new FormControl('', Validators.required) - }); + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iosService: IosService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private iosConfigurationService: IosConfigurationService, + private router: Router + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + path: new FormControl('', Validators.required), + initialConfig: new FormControl('', Validators.required), + }); - this.memoryForm = this.formBuilder.group({ - ram: new FormControl('', Validators.required), - nvram: new FormControl('', Validators.required), - iomemory: new FormControl('', Validators.required), - disk0: new FormControl('', Validators.required), - disk1: new FormControl('', Validators.required), - }); + this.memoryForm = this.formBuilder.group({ + ram: new FormControl('', Validators.required), + nvram: new FormControl('', Validators.required), + iomemory: new FormControl('', Validators.required), + disk0: new FormControl('', Validators.required), + disk1: new FormControl('', Validators.required), + }); - this.advancedForm = this.formBuilder.group({ - systemId: new FormControl('', Validators.required), - idlemax: new FormControl('', Validators.required), - idlesleep: new FormControl('', Validators.required), - execarea: new FormControl('', Validators.required), - }); + this.advancedForm = this.formBuilder.group({ + systemId: new FormControl('', Validators.required), + idlemax: new FormControl('', Validators.required), + idlesleep: new FormControl('', Validators.required), + execarea: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.iosService.getTemplate(this.server, template_id).subscribe((iosTemplate: IosTemplate) => { + this.iosTemplate = iosTemplate; + + this.fillAdaptersData(); + }); + }); + } + + getConfiguration() { + this.networkModules = this.iosConfigurationService.getNetworkModules(); + this.networkAdaptersForPlatform = this.iosConfigurationService.getNetworkAdaptersForPlatform(); + this.networkAdapters = this.iosConfigurationService.getNetworkAdapters(); + this.platforms = this.iosConfigurationService.getAvailablePlatforms(); + this.platformsWithEtherSwitchRouterOption = this.iosConfigurationService.getPlatformsWithEtherSwitchRouterOption(); + this.platformsWithChassis = this.iosConfigurationService.getPlatformsWithChassis(); + this.chassis = this.iosConfigurationService.getChassis(); + this.defaultRam = this.iosConfigurationService.getDefaultRamSettings(); + this.consoleTypes = this.iosConfigurationService.getConsoleTypes(); + } + + fillAdaptersData() { + if (this.iosTemplate.slot0) this.networkAdaptersForTemplate[0] = this.iosTemplate.slot0; + if (this.iosTemplate.slot1) this.networkAdaptersForTemplate[1] = this.iosTemplate.slot1; + if (this.iosTemplate.slot2) this.networkAdaptersForTemplate[2] = this.iosTemplate.slot2; + if (this.iosTemplate.slot3) this.networkAdaptersForTemplate[3] = this.iosTemplate.slot3; + if (this.iosTemplate.slot4) this.networkAdaptersForTemplate[4] = this.iosTemplate.slot4; + if (this.iosTemplate.slot5) this.networkAdaptersForTemplate[5] = this.iosTemplate.slot5; + if (this.iosTemplate.slot6) this.networkAdaptersForTemplate[6] = this.iosTemplate.slot6; + if (this.iosTemplate.slot7) this.networkAdaptersForTemplate[7] = this.iosTemplate.slot7; + } + + completeAdaptersData() { + if (this.networkAdaptersForTemplate[0]) this.iosTemplate.slot0 = this.networkAdaptersForTemplate[0]; + if (this.networkAdaptersForTemplate[1]) this.iosTemplate.slot1 = this.networkAdaptersForTemplate[1]; + if (this.networkAdaptersForTemplate[2]) this.iosTemplate.slot2 = this.networkAdaptersForTemplate[2]; + if (this.networkAdaptersForTemplate[3]) this.iosTemplate.slot3 = this.networkAdaptersForTemplate[3]; + if (this.networkAdaptersForTemplate[4]) this.iosTemplate.slot4 = this.networkAdaptersForTemplate[4]; + if (this.networkAdaptersForTemplate[5]) this.iosTemplate.slot5 = this.networkAdaptersForTemplate[5]; + if (this.networkAdaptersForTemplate[6]) this.iosTemplate.slot6 = this.networkAdaptersForTemplate[6]; + if (this.networkAdaptersForTemplate[7]) this.iosTemplate.slot7 = this.networkAdaptersForTemplate[7]; + } + + onSave() { + if (this.generalSettingsForm.invalid || this.memoryForm.invalid || this.advancedForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.completeAdaptersData(); + + this.iosService.saveTemplate(this.server, this.iosTemplate).subscribe((iosTemplate: IosTemplate) => { + this.toasterService.success('Changes saved'); + }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'dynamips', 'templates']); + } - this.getConfiguration(); - this.iosService.getTemplate(this.server, template_id).subscribe((iosTemplate: IosTemplate) => { - this.iosTemplate = iosTemplate; + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - this.fillAdaptersData(); - }); - }); - } - - getConfiguration() { - this.networkModules = this.iosConfigurationService.getNetworkModules(); - this.networkAdaptersForPlatform = this.iosConfigurationService.getNetworkAdaptersForPlatform(); - this.networkAdapters = this.iosConfigurationService.getNetworkAdapters(); - this.platforms = this.iosConfigurationService.getAvailablePlatforms(); - this.platformsWithEtherSwitchRouterOption = this.iosConfigurationService.getPlatformsWithEtherSwitchRouterOption(); - this.platformsWithChassis = this.iosConfigurationService.getPlatformsWithChassis(); - this.chassis = this.iosConfigurationService.getChassis(); - this.defaultRam = this.iosConfigurationService.getDefaultRamSettings(); - this.consoleTypes = this.iosConfigurationService.getConsoleTypes(); - } - - fillAdaptersData() { - if (this.iosTemplate.slot0) this.networkAdaptersForTemplate[0] = this.iosTemplate.slot0; - if (this.iosTemplate.slot1) this.networkAdaptersForTemplate[1] = this.iosTemplate.slot1; - if (this.iosTemplate.slot2) this.networkAdaptersForTemplate[2] = this.iosTemplate.slot2; - if (this.iosTemplate.slot3) this.networkAdaptersForTemplate[3] = this.iosTemplate.slot3; - if (this.iosTemplate.slot4) this.networkAdaptersForTemplate[4] = this.iosTemplate.slot4; - if (this.iosTemplate.slot5) this.networkAdaptersForTemplate[5] = this.iosTemplate.slot5; - if (this.iosTemplate.slot6) this.networkAdaptersForTemplate[6] = this.iosTemplate.slot6; - if (this.iosTemplate.slot7) this.networkAdaptersForTemplate[7] = this.iosTemplate.slot7; - } - - completeAdaptersData() { - if (this.networkAdaptersForTemplate[0]) this.iosTemplate.slot0 = this.networkAdaptersForTemplate[0]; - if (this.networkAdaptersForTemplate[1]) this.iosTemplate.slot1 = this.networkAdaptersForTemplate[1]; - if (this.networkAdaptersForTemplate[2]) this.iosTemplate.slot2 = this.networkAdaptersForTemplate[2]; - if (this.networkAdaptersForTemplate[3]) this.iosTemplate.slot3 = this.networkAdaptersForTemplate[3]; - if (this.networkAdaptersForTemplate[4]) this.iosTemplate.slot4 = this.networkAdaptersForTemplate[4]; - if (this.networkAdaptersForTemplate[5]) this.iosTemplate.slot5 = this.networkAdaptersForTemplate[5]; - if (this.networkAdaptersForTemplate[6]) this.iosTemplate.slot6 = this.networkAdaptersForTemplate[6]; - if (this.networkAdaptersForTemplate[7]) this.iosTemplate.slot7 = this.networkAdaptersForTemplate[7]; - } - - onSave() { - if (this.generalSettingsForm.invalid || this.memoryForm.invalid || this.advancedForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.completeAdaptersData(); - - this.iosService.saveTemplate(this.server, this.iosTemplate).subscribe((iosTemplate: IosTemplate) => { - this.toasterService.success("Changes saved"); - }); - } - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'dynamips', 'templates']); - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.iosTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.iosTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.html b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.html index 9a573ad3..d522abb8 100644 --- a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.html +++ b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.html @@ -1,35 +1,49 @@
-
-
-

IOS router templates

- - -
+
+
+

IOS router templates

+ +
- -
-
- -
- {{template.name}} - - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + + +
+
+
- - + diff --git a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.spec.ts b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.spec.ts index 18b42cb1..62bb84f7 100644 --- a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.spec.ts +++ b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { IosTemplate } from '../../../../models/templates/ios-template'; -import { IosTemplatesComponent } from './ios-templates.component'; import { IosService } from '../../../../services/ios.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { IosTemplatesComponent } from './ios-templates.component'; export class MockedIosService { - public getTemplates(server: Server) { - return of([{} as IosTemplate]); - } + public getTemplates(server: Server) { + return of([{} as IosTemplate]); + } } describe('IosTemplatesComponent', () => { - let component: IosTemplatesComponent; - let fixture: ComponentFixture; + let component: IosTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedIosService = new MockedIosService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: IosService, useValue: mockedIosService } - ], - declarations: [ - IosTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedIosService = new MockedIosService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(IosTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: IosService, useValue: mockedIosService }, + ], + declarations: [IosTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IosTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts index d8536d8f..2cc9a6b4 100644 --- a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts +++ b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts @@ -1,53 +1,60 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { IosService } from '../../../../services/ios.service'; +import { Server } from '../../../../models/server'; import { IosTemplate } from '../../../../models/templates/ios-template'; -import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; - +import { IosService } from '../../../../services/ios.service'; +import { ServerService } from '../../../../services/server.service'; +import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ - selector: 'app-ios-templates', - templateUrl: './ios-templates.component.html', - styleUrls: ['./ios-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-ios-templates', + templateUrl: './ios-templates.component.html', + styleUrls: ['./ios-templates.component.scss', '../../preferences.component.scss'], }) export class IosTemplatesComponent implements OnInit { - server: Server; - iosTemplates: IosTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + iosTemplates: IosTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iosService: IosService, - private router: Router - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iosService: IosService, + private router: Router + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.iosService.getTemplates(this.server).subscribe((templates: IosTemplate[]) => { - this.iosTemplates = templates.filter((elem) => elem.template_type === 'dynamips' && !elem.builtin); - }); - } - - deleteTemplate(template: VpcsTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + getTemplates() { + this.iosService.getTemplates(this.server).subscribe((templates: IosTemplate[]) => { + this.iosTemplates = templates.filter((elem) => elem.template_type === 'dynamips' && !elem.builtin); + }); + } - onDeleteEvent() { - this.getTemplates(); - } + deleteTemplate(template: VpcsTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - copyTemplate(template: IosTemplate) { - this.router.navigate(['/server', this.server.id, 'preferences', 'dynamips', 'templates', template.template_id, 'copy']); - } + onDeleteEvent() { + this.getTemplates(); + } + + copyTemplate(template: IosTemplate) { + this.router.navigate([ + '/server', + this.server.id, + 'preferences', + 'dynamips', + 'templates', + template.template_id, + 'copy', + ]); + } } diff --git a/src/app/components/preferences/general/general-preferences.component.html b/src/app/components/preferences/general/general-preferences.component.html index 86867d4d..a521a9ac 100644 --- a/src/app/components/preferences/general/general-preferences.component.html +++ b/src/app/components/preferences/general/general-preferences.component.html @@ -1,10 +1,10 @@
-
-
-

General preferences

-
-
-
-
+
+
+

General preferences

+
+
+
+
diff --git a/src/app/components/preferences/general/general-preferences.component.spec.ts b/src/app/components/preferences/general/general-preferences.component.spec.ts index 7b678c20..4cfd7d57 100644 --- a/src/app/components/preferences/general/general-preferences.component.spec.ts +++ b/src/app/components/preferences/general/general-preferences.component.spec.ts @@ -1,3 +1,5 @@ +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; @@ -5,43 +7,48 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute } from '@angular/router'; -import { CommonModule } from '@angular/common'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; -import { GeneralPreferencesComponent } from './general-preferences.component'; import { MockedActivatedRoute } from '../preferences.component.spec'; +import { GeneralPreferencesComponent } from './general-preferences.component'; describe('GeneralPreferencesComponent', () => { - let component: GeneralPreferencesComponent; - let fixture: ComponentFixture; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - } - ], - declarations: [ - GeneralPreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(GeneralPreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + let component: GeneralPreferencesComponent; + let fixture: ComponentFixture; + let activatedRoute = new MockedActivatedRoute().get(); - it('should set correct server id', () => { - expect(component.serverId).toBe('1'); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + ], + declarations: [GeneralPreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GeneralPreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set correct server id', () => { + expect(component.serverId).toBe('1'); + }); }); diff --git a/src/app/components/preferences/general/general-preferences.component.ts b/src/app/components/preferences/general/general-preferences.component.ts index 0863e2fe..e9f24013 100644 --- a/src/app/components/preferences/general/general-preferences.component.ts +++ b/src/app/components/preferences/general/general-preferences.component.ts @@ -1,20 +1,17 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; - @Component({ - selector: 'app-general-preferences', - templateUrl: './general-preferences.component.html', - styleUrls: ['./general-preferences.component.scss'] + selector: 'app-general-preferences', + templateUrl: './general-preferences.component.html', + styleUrls: ['./general-preferences.component.scss'], }) export class GeneralPreferencesComponent implements OnInit { - public serverId: string = ""; + public serverId: string = ''; - constructor( - private route: ActivatedRoute - ) {} + constructor(private route: ActivatedRoute) {} - ngOnInit() { - this.serverId = this.route.snapshot.paramMap.get("server_id"); - } + ngOnInit() { + this.serverId = this.route.snapshot.paramMap.get('server_id'); + } } diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.html b/src/app/components/preferences/gns3vm/gns3vm.component.html index 3e249db6..8f14cd4f 100644 --- a/src/app/components/preferences/gns3vm/gns3vm.component.html +++ b/src/app/components/preferences/gns3vm/gns3vm.component.html @@ -1,52 +1,66 @@
-
-
-

GNS3 VM preferences

-
+
+
+

GNS3 VM preferences

-
- - - Enable the GNS3 VM - - - - - {{engine.name}} - - - - - - - {{vm.vmname}} - - - - - Run the VM in headless mode - -
- - - - - - MB - - - - -
- - keep the GNS3 VM running - suspend the GNS3 VM - stop the GNS3 VM - -
-
- - -
+
+
+ + + Enable the GNS3 VM + + + + + {{ engine.name }} + + + + + + + {{ vm.vmname }} + + + + + Run the VM in headless mode + +
+ + + + + + MB + + + + +
+ + keep the GNS3 VM running + suspend the GNS3 VM + stop the GNS3 VM + +
+
+ +
+
diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.scss b/src/app/components/preferences/gns3vm/gns3vm.component.scss index 98ba27a0..d1ec18bf 100644 --- a/src/app/components/preferences/gns3vm/gns3vm.component.scss +++ b/src/app/components/preferences/gns3vm/gns3vm.component.scss @@ -1,12 +1,12 @@ .form-field { - width: 100%; + width: 100%; } .select { - width: 100%; + width: 100%; } .radio-selection { - display: flex; - justify-content: space-between; + display: flex; + justify-content: space-between; } diff --git a/src/app/components/preferences/gns3vm/gns3vm.component.ts b/src/app/components/preferences/gns3vm/gns3vm.component.ts index b49ba281..422facdc 100644 --- a/src/app/components/preferences/gns3vm/gns3vm.component.ts +++ b/src/app/components/preferences/gns3vm/gns3vm.component.ts @@ -1,90 +1,89 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { Gns3vmService } from '../../../services/gns3vm.service'; import { Gns3vm } from '../../../models/gns3vm/gns3vm'; -import { Server } from '../../../models/server'; -import { ServerService } from '../../../services/server.service'; import { Gns3vmEngine } from '../../../models/gns3vm/gns3vmEngine'; -import { FormBuilder, FormControl, Validators, FormGroup } from '@angular/forms'; -import { ToasterService } from '../../../services/toaster.service'; import { VM } from '../../../models/gns3vm/vm'; - +import { Server } from '../../../models/server'; +import { Gns3vmService } from '../../../services/gns3vm.service'; +import { ServerService } from '../../../services/server.service'; +import { ToasterService } from '../../../services/toaster.service'; @Component({ - selector: 'app-gns3vm', - templateUrl: './gns3vm.component.html', - styleUrls: ['./gns3vm.component.scss'] + selector: 'app-gns3vm', + templateUrl: './gns3vm.component.html', + styleUrls: ['./gns3vm.component.scss'], }) export class Gns3vmComponent implements OnInit { - public server: Server; - public gns3vm: Gns3vm; - public vmEngines: Gns3vmEngine[]; - public vms: VM[] = []; - public vmForm: FormGroup; - public port: number; + public server: Server; + public gns3vm: Gns3vm; + public vmEngines: Gns3vmEngine[]; + public vms: VM[] = []; + public vmForm: FormGroup; + public port: number; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private gns3vmService: Gns3vmService, - private router: Router, - private formBuilder: FormBuilder, - private toasterService: ToasterService - ) { - this.vmForm = this.formBuilder.group({ - ram: new FormControl(null, [Validators.required]), - vcpus: new FormControl(null, [Validators.required]) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private gns3vmService: Gns3vmService, + private router: Router, + private formBuilder: FormBuilder, + private toasterService: ToasterService + ) { + this.vmForm = this.formBuilder.group({ + ram: new FormControl(null, [Validators.required]), + vcpus: new FormControl(null, [Validators.required]), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.gns3vmService.getGns3vm(this.server).subscribe((vm: Gns3vm) => { + this.gns3vm = vm; + this.vmForm.controls['ram'].setValue(this.gns3vm.ram); + this.vmForm.controls['vcpus'].setValue(this.gns3vm.vcpus); + if (this.gns3vm.port) this.port = this.gns3vm.port; + this.gns3vmService.getGns3vmEngines(this.server).subscribe((vmEngines: Gns3vmEngine[]) => { + this.vmEngines = vmEngines; }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.gns3vmService.getGns3vm(this.server).subscribe((vm: Gns3vm) => { - this.gns3vm = vm; - this.vmForm.controls['ram'].setValue(this.gns3vm.ram); - this.vmForm.controls['vcpus'].setValue(this.gns3vm.vcpus); - if (this.gns3vm.port) this.port = this.gns3vm.port; - this.gns3vmService.getGns3vmEngines(this.server).subscribe((vmEngines: Gns3vmEngine[]) => { - this.vmEngines = vmEngines; - }); - this.gns3vmService.getVms(this.server, this.gns3vm.engine).subscribe((vms: VM[]) => { - this.vms = vms; - }); - }); + this.gns3vmService.getVms(this.server, this.gns3vm.engine).subscribe((vms: VM[]) => { + this.vms = vms; }); - } + }); + }); + } - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences']); - } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences']); + } - setCloseAction(action: string) { - this.gns3vm.when_exit = action; - } + setCloseAction(action: string) { + this.gns3vm.when_exit = action; + } - changeVmEngine(event) { - this.gns3vmService.getVms(this.server, event.value).subscribe( - (vms: VM[]) => { - this.vms = vms; - }, - error => {} - ); - } + changeVmEngine(event) { + this.gns3vmService.getVms(this.server, event.value).subscribe( + (vms: VM[]) => { + this.vms = vms; + }, + (error) => {} + ); + } - save() { - if ((this.vmForm.valid && this.gns3vm.vmname) || (this.gns3vm.engine==='remote' && this.gns3vm.vmname)) { - this.gns3vm.ram = this.vmForm.get('ram').value; - this.gns3vm.vcpus= this.vmForm.get('vcpus').value; - if (this.port) this.gns3vm.port = this.port; + save() { + if ((this.vmForm.valid && this.gns3vm.vmname) || (this.gns3vm.engine === 'remote' && this.gns3vm.vmname)) { + this.gns3vm.ram = this.vmForm.get('ram').value; + this.gns3vm.vcpus = this.vmForm.get('vcpus').value; + if (this.port) this.gns3vm.port = this.port; - this.gns3vmService.updateGns3vm(this.server, this.gns3vm).subscribe(() => { - this.toasterService.success('GNS3 VM updated.'); - }); - this.goBack(); - } else { - this.toasterService.error('Fill all required fields with correct values.'); - } + this.gns3vmService.updateGns3vm(this.server, this.gns3vm).subscribe(() => { + this.toasterService.success('GNS3 VM updated.'); + }); + this.goBack(); + } else { + this.toasterService.error('Fill all required fields with correct values.'); } + } } diff --git a/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.html b/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.html index 021bdd78..28c73807 100644 --- a/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.html +++ b/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.html @@ -1,78 +1,85 @@
-
-
-

New IOU device template

-
+
+
+

New IOU device template

-
-
- - - - Run this IOU device locally - Run this IOU device on the GNS3 VM - - +
+
+
+ + + + Run this IOU device locally + Run this IOU device on the GNS3 VM + + - -
- - - -
-
+ +
+ + + +
+
- -
- - Existing image - New image - - - - - {{type}} - - - - - - - {{image.path}} - - - -
- - - - - -
-
-
-
-
-
- - -
+ +
+ + Existing image + New image + + + + + {{ type }} + + + + + + + {{ image.path }} + + + +
+ + + + + +
+
+
+
+
+ + +
+
diff --git a/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.spec.ts b/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.spec.ts index a2e52326..04b9e29d 100644 --- a/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.spec.ts +++ b/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.spec.ts @@ -1,4 +1,7 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -9,116 +12,113 @@ import { MatSelectModule } from '@angular/material/select'; import { MatStepperModule } from '@angular/material/stepper'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; +import { IouTemplate } from '../../../../models/templates/iou-template'; +import { IouConfigurationService } from '../../../../services/iou-configuration.service'; +import { IouService } from '../../../../services/iou.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { IouTemplate } from '../../../../models/templates/iou-template'; import { AddIouTemplateComponent } from './add-iou-template.component'; -import { IouService } from '../../../../services/iou.service'; -import { IouConfigurationService } from '../../../../services/iou-configuration.service'; export class MockedIouService { - public addTemplate(server: Server, iouTemplate: IouTemplate) { - return of(iouTemplate); - } + public addTemplate(server: Server, iouTemplate: IouTemplate) { + return of(iouTemplate); + } } //Tests disabled due to instability xdescribe('AddIouTemplateComponent', () => { - let component: AddIouTemplateComponent; - let fixture: ComponentFixture; + let component: AddIouTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedIouService = new MockedIouService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - MatStepperModule, - FormsModule, - MatTableModule, - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - ReactiveFormsModule, - MatSelectModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/iou/templates', component: AddIouTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: IouService, useValue: mockedIouService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: TemplateMocksService, useClass: TemplateMocksService }, - { provide: IouConfigurationService, useClass: IouConfigurationService } - ], - declarations: [ - AddIouTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedIouService = new MockedIouService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(AddIouTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatStepperModule, + FormsModule, + MatTableModule, + MatAutocompleteModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule, + MatSelectModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/iou/templates', component: AddIouTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: IouService, useValue: mockedIouService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + { provide: IouConfigurationService, useClass: IouConfigurationService }, + ], + declarations: [AddIouTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AddIouTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call add template', () => { - spyOn(mockedIouService, 'addTemplate').and.returnValue(of({} as IouTemplate)); - component.templateNameForm.controls['templateName'].setValue('sample name'); - component.imageForm.controls['imageName'].setValue('sample name'); - component.newImageSelected = true; - component.server = {id: 1} as Server; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call add template', () => { + spyOn(mockedIouService, 'addTemplate').and.returnValue(of({} as IouTemplate)); + component.templateNameForm.controls['templateName'].setValue('sample name'); + component.imageForm.controls['imageName'].setValue('sample name'); + component.newImageSelected = true; + component.server = { id: 1 } as Server; - expect(mockedIouService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when template name is empty', () => { - spyOn(mockedIouService, 'addTemplate').and.returnValue(of({} as IouTemplate)); - component.imageForm.controls['imageName'].setValue('sample name'); - component.newImageSelected = true; - component.server = {id: 1} as Server; + expect(mockedIouService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when template name is empty', () => { + spyOn(mockedIouService, 'addTemplate').and.returnValue(of({} as IouTemplate)); + component.imageForm.controls['imageName'].setValue('sample name'); + component.newImageSelected = true; + component.server = { id: 1 } as Server; - expect(mockedIouService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when image is not entered', () => { - spyOn(mockedIouService, 'addTemplate').and.returnValue(of({} as IouTemplate)); - component.templateNameForm.controls['templateName'].setValue('sample name'); - component.newImageSelected = true; - component.server = {id: 1} as Server; + expect(mockedIouService.addTemplate).not.toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when image is not entered', () => { + spyOn(mockedIouService, 'addTemplate').and.returnValue(of({} as IouTemplate)); + component.templateNameForm.controls['templateName'].setValue('sample name'); + component.newImageSelected = true; + component.server = { id: 1 } as Server; - expect(mockedIouService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedIouService.addTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.ts b/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.ts index 0927724d..13a7568c 100644 --- a/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.ts +++ b/src/app/components/preferences/ios-on-unix/add-iou-template/add-iou-template.component.ts @@ -1,152 +1,154 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { IouTemplate } from '../../../../models/templates/iou-template'; -import { IouService } from '../../../../services/iou.service'; -import { ComputeService } from '../../../../services/compute.service'; import { Compute } from '../../../../models/compute'; -import { FileUploader, FileItem, ParsedResponseHeaders } from 'ng2-file-upload'; import { IouImage } from '../../../../models/iou/iou-image'; - +import { Server } from '../../../../models/server'; +import { IouTemplate } from '../../../../models/templates/iou-template'; +import { ComputeService } from '../../../../services/compute.service'; +import { IouService } from '../../../../services/iou.service'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-add-iou-template', - templateUrl: './add-iou-template.component.html', - styleUrls: ['./add-iou-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-iou-template', + templateUrl: './add-iou-template.component.html', + styleUrls: ['./add-iou-template.component.scss', '../../preferences.component.scss'], }) export class AddIouTemplateComponent implements OnInit { - server: Server; - iouTemplate: IouTemplate; - isRemoteComputerChosen: boolean = false; - newImageSelected: boolean = false; - types: string[] = ['L2 image', 'L3 image']; - selectedType: string; - iouImages: IouImage[] = []; - uploader: FileUploader; + server: Server; + iouTemplate: IouTemplate; + isRemoteComputerChosen: boolean = false; + newImageSelected: boolean = false; + types: string[] = ['L2 image', 'L3 image']; + selectedType: string; + iouImages: IouImage[] = []; + uploader: FileUploader; - templateNameForm: FormGroup; - imageForm: FormGroup; + templateNameForm: FormGroup; + imageForm: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iouService: IouService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder, - private templateMocksService: TemplateMocksService, - private computeService: ComputeService + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iouService: IouService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder, + private templateMocksService: TemplateMocksService, + private computeService: ComputeService + ) { + this.iouTemplate = new IouTemplate(); + + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl(null, Validators.required), + }); + + this.imageForm = this.formBuilder.group({ + imageName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + this.uploader = new FileUploader({}); + this.uploader.onAfterAddingFile = (file) => { + file.withCredentials = false; + }; + this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { + this.toasterService.error('An error occured: ' + response); + }; + this.uploader.onSuccessItem = ( + item: FileItem, + response: string, + status: number, + headers: ParsedResponseHeaders + ) => { + this.getImages(); + this.toasterService.success('Image uploaded'); + }; + + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getImages(); + + this.templateMocksService.getIouTemplate().subscribe((iouTemplate: IouTemplate) => { + this.iouTemplate = iouTemplate; + }); + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + getImages() { + this.iouService.getImages(this.server).subscribe((images: IouImage[]) => { + this.iouImages = images; + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; + } + } + + setDiskImage(value: string) { + this.newImageSelected = value === 'newImage'; + } + + uploadImageFile(event): void { + let name = event.target.files[0].name; + this.imageForm.controls['imageName'].setValue(name); + + const url = this.iouService.getImagePath(this.server, name); + this.uploader.queue.forEach((elem) => (elem.url = url)); + + const itemToUpload = this.uploader.queue[0]; + (itemToUpload as any).options.disableMultipart = true; + + this.uploader.uploadItem(itemToUpload); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates']); + } + + addTemplate() { + if ( + !this.templateNameForm.invalid && + ((this.newImageSelected && !this.imageForm.invalid) || (!this.newImageSelected && this.iouTemplate.path)) ) { - this.iouTemplate = new IouTemplate(); + this.iouTemplate.template_id = uuid(); + this.iouTemplate.name = this.templateNameForm.get('templateName').value; + if (this.newImageSelected) this.iouTemplate.path = this.imageForm.get('imageName').value; + this.iouTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - this.templateNameForm = this.formBuilder.group({ - templateName: new FormControl(null, Validators.required) - }); + if (this.selectedType === 'L2 image') { + this.iouTemplate.ethernet_adapters = 4; + this.iouTemplate.serial_adapters = 0; + } else if (this.selectedType === 'L3 image') { + this.iouTemplate.ethernet_adapters = 2; + this.iouTemplate.serial_adapters = 2; + } - this.imageForm = this.formBuilder.group({ - imageName: new FormControl('', Validators.required) - }); - } - - ngOnInit() { - this.uploader = new FileUploader({}); - this.uploader.onAfterAddingFile = file => { - file.withCredentials = false; - }; - this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { - this.toasterService.error('An error occured: ' + response); - }; - this.uploader.onSuccessItem = ( - item: FileItem, - response: string, - status: number, - headers: ParsedResponseHeaders - ) => { - this.getImages(); - this.toasterService.success('Image uploaded'); - }; - - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getImages(); - - this.templateMocksService.getIouTemplate().subscribe((iouTemplate: IouTemplate) => { - this.iouTemplate = iouTemplate; - }) - - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - }); - } - - getImages() { - this.iouService.getImages(this.server).subscribe((images: IouImage[]) => { - this.iouImages = images; - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - setDiskImage(value: string) { - this.newImageSelected = value === "newImage"; - } - - uploadImageFile(event): void { - let name = event.target.files[0].name; - this.imageForm.controls['imageName'].setValue(name); - - const url = this.iouService.getImagePath(this.server, name); - this.uploader.queue.forEach(elem => (elem.url = url)); - - const itemToUpload = this.uploader.queue[0]; - (itemToUpload as any).options.disableMultipart = true; - - this.uploader.uploadItem(itemToUpload); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates']); - } - - addTemplate() { - if (!this.templateNameForm.invalid && ((this.newImageSelected && !this.imageForm.invalid) || (!this.newImageSelected && this.iouTemplate.path))) { - this.iouTemplate.template_id = uuid(); - this.iouTemplate.name = this.templateNameForm.get("templateName").value; - if (this.newImageSelected) this.iouTemplate.path = this.imageForm.get("imageName").value; - this.iouTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - if (this.selectedType === 'L2 image') { - this.iouTemplate.ethernet_adapters = 4; - this.iouTemplate.serial_adapters = 0; - } else if (this.selectedType === 'L3 image') { - this.iouTemplate.ethernet_adapters = 2; - this.iouTemplate.serial_adapters = 2; - } - - this.iouService.addTemplate(this.server, this.iouTemplate).subscribe((template: IouTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + this.iouService.addTemplate(this.server, this.iouTemplate).subscribe((template: IouTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.html b/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.html index 2c9a0908..b9ca4669 100644 --- a/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.html +++ b/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.html @@ -1,24 +1,20 @@
-
-
-

Copy IOU device template

-
+
+
+

Copy IOU device template

-
- -
- - - -
-
-
- - -
+
+
+ +
+ + + +
+
+
+ +
+
diff --git a/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.ts b/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.ts index a430d34a..9bff8082 100644 --- a/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.ts +++ b/src/app/components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component.ts @@ -1,66 +1,64 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; +import { Server } from '../../../../models/server'; import { IouTemplate } from '../../../../models/templates/iou-template'; import { IouService } from '../../../../services/iou.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-copy-iou-template', - templateUrl: './copy-iou-template.component.html', - styleUrls: ['./copy-iou-template.component.scss', '../../preferences.component.scss'] + selector: 'app-copy-iou-template', + templateUrl: './copy-iou-template.component.html', + styleUrls: ['./copy-iou-template.component.scss', '../../preferences.component.scss'], }) export class CopyIouTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - iouTemplate: IouTemplate; - templateNameForm: FormGroup; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private qemuService: IouService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder - ) { - this.templateNameForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required) - }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.qemuService.getTemplate(this.server, template_id).subscribe((iouTemplate: IouTemplate) => { - this.iouTemplate = iouTemplate; - this.templateName = `Copy of ${this.iouTemplate.name}`; - }) - - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates']); - } - - addTemplate() { - if (!this.templateNameForm.invalid) { - this.iouTemplate.template_id = uuid(); - this.iouTemplate.name = this.templateName; - - this.qemuService.addTemplate(this.server, this.iouTemplate).subscribe((template: IouTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + server: Server; + templateName: string = ''; + iouTemplate: IouTemplate; + templateNameForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private qemuService: IouService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.qemuService.getTemplate(this.server, template_id).subscribe((iouTemplate: IouTemplate) => { + this.iouTemplate = iouTemplate; + this.templateName = `Copy of ${this.iouTemplate.name}`; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates']); + } + + addTemplate() { + if (!this.templateNameForm.invalid) { + this.iouTemplate.template_id = uuid(); + this.iouTemplate.name = this.templateName; + + this.qemuService.addTemplate(this.server, this.iouTemplate).subscribe((template: IouTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.html b/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.html index f72a597a..6d8cc52b 100644 --- a/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.html +++ b/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.html @@ -1,113 +1,156 @@ -
-
-
-

IOU device configuration

-
+
+
+
+

IOU device configuration

-
- - - - - General settings - - -
- - - - - - - - - -

- - - - {{category[0]}} - - - - - - - - - - - - - - -
- - - - {{type}} - - - - - Auto start console -
- - Enable layer 1 keepalive messages (non-functional) -
- - Use default IOU values for memories - - - - MB - - - - MB - -
- - - - Network - - -
- - - - - - -
-
- - - - Usage - - - - - - -
-
- - -
+
+
+ + + + General settings + +
+ + + + + + + + + +

+ + + + {{ category[0] }} + + + + + + + + + + + + + + +
+ + + + {{ type }} + + + + Auto start console
+ + Enable layer 1 keepalive messages (non-functional)
+ Use default IOU values for memories + + + MB + + + + MB + +
+ + + Network + +
+ + + + + + +
+
+ + + Usage + + + + + +
+
+ +
+
- + diff --git a/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.spec.ts b/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.spec.ts index 29d7983b..ddeae449 100644 --- a/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.spec.ts +++ b/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.spec.ts @@ -1,84 +1,92 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { IouTemplate } from '../../../../models/templates/iou-template'; -import { IouTemplateDetailsComponent } from './iou-template-details.component'; -import { IouService } from '../../../../services/iou.service'; import { IouConfigurationService } from '../../../../services/iou-configuration.service'; +import { IouService } from '../../../../services/iou.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { IouTemplateDetailsComponent } from './iou-template-details.component'; export class MockedIouService { - public getTemplate(server: Server, template_id: string) { - return of({} as IouTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as IouTemplate); + } - public saveTemplate(server: Server, iouTemplate: IouTemplate) { - return of(iouTemplate); - } + public saveTemplate(server: Server, iouTemplate: IouTemplate) { + return of(iouTemplate); + } } describe('IouTemplateDetailsComponent', () => { - let component: IouTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: IouTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedIouService = new MockedIouService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: IouService, useValue: mockedIouService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: IouConfigurationService, useClass: IouConfigurationService } - ], - declarations: [ - IouTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedIouService = new MockedIouService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(IouTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: IouService, useValue: mockedIouService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: IouConfigurationService, useClass: IouConfigurationService }, + ], + declarations: [IouTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IouTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedIouService, 'saveTemplate').and.returnValue(of({} as IouTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.generalSettingsForm.controls['path'].setValue('path'); - component.generalSettingsForm.controls['initialConfig'].setValue('txt'); - component.networkForm.controls['ethernetAdapters'].setValue('1'); - component.networkForm.controls['serialAdapters'].setValue('1'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedIouService, 'saveTemplate').and.returnValue(of({} as IouTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['path'].setValue('path'); + component.generalSettingsForm.controls['initialConfig'].setValue('txt'); + component.networkForm.controls['ethernetAdapters'].setValue('1'); + component.networkForm.controls['serialAdapters'].setValue('1'); - expect(mockedIouService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedIouService.saveTemplate).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.ts b/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.ts index 3427591b..e4a38306 100644 --- a/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.ts +++ b/src/app/components/preferences/ios-on-unix/iou-template-details/iou-template-details.component.ts @@ -1,98 +1,97 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; import { IouTemplate } from '../../../../models/templates/iou-template'; -import { IouService } from '../../../../services/iou.service'; import { IouConfigurationService } from '../../../../services/iou-configuration.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { IouService } from '../../../../services/iou.service'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-iou-template-details', - templateUrl: './iou-template-details.component.html', - styleUrls: ['./iou-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-iou-template-details', + templateUrl: './iou-template-details.component.html', + styleUrls: ['./iou-template-details.component.scss', '../../preferences.component.scss'], }) export class IouTemplateDetailsComponent implements OnInit { - server: Server; - iouTemplate: IouTemplate; + server: Server; + iouTemplate: IouTemplate; - isSymbolSelectionOpened: boolean = false; - defaultSettings: boolean = true; + isSymbolSelectionOpened: boolean = false; + defaultSettings: boolean = true; - consoleTypes: string[] = []; - consoleResolutions: string[] = []; - categories = []; + consoleTypes: string[] = []; + consoleResolutions: string[] = []; + categories = []; - generalSettingsForm: FormGroup; - networkForm: FormGroup; + generalSettingsForm: FormGroup; + networkForm: FormGroup; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iouService: IouService, - private toasterService: ToasterService, - private configurationService: IouConfigurationService, - private router: Router, - private formBuilder: FormBuilder - ){ - this.generalSettingsForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required), - path: new FormControl('', Validators.required), - initialConfig: new FormControl('', Validators.required) - }); + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iouService: IouService, + private toasterService: ToasterService, + private configurationService: IouConfigurationService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + path: new FormControl('', Validators.required), + initialConfig: new FormControl('', Validators.required), + }); - this.networkForm = this.formBuilder.group({ - ethernetAdapters: new FormControl('', Validators.required), - serialAdapters: new FormControl('', Validators.required) - }); + this.networkForm = this.formBuilder.group({ + ethernetAdapters: new FormControl('', Validators.required), + serialAdapters: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.iouService.getTemplate(this.server, template_id).subscribe((iouTemplate: IouTemplate) => { + this.iouTemplate = iouTemplate; + }); + }); + } + + getConfiguration() { + this.consoleTypes = this.configurationService.getConsoleTypes(); + this.categories = this.configurationService.getCategories(); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates']); + } + + onSave() { + if (this.generalSettingsForm.invalid || this.networkForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.iouService.saveTemplate(this.server, this.iouTemplate).subscribe(() => { + this.toasterService.success('Changes saved'); + }); } + } - ngOnInit(){ - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.getConfiguration(); - this.iouService.getTemplate(this.server, template_id).subscribe((iouTemplate: IouTemplate) => { - this.iouTemplate = iouTemplate; - }); - }); - } + uploadImageFile(event) { + this.iouTemplate.path = event.target.files[0].name; + } - getConfiguration(){ - this.consoleTypes = this.configurationService.getConsoleTypes(); - this.categories = this.configurationService.getCategories(); - } + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates']); - } - - onSave(){ - if (this.generalSettingsForm.invalid || this.networkForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.iouService.saveTemplate(this.server, this.iouTemplate).subscribe(() => { - this.toasterService.success("Changes saved"); - }); - } - } - - uploadImageFile(event) { - this.iouTemplate.path = event.target.files[0].name; - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.iouTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.iouTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.html b/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.html index 617cc70c..72d55104 100644 --- a/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.html +++ b/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.html @@ -1,35 +1,49 @@
-
-
-

IOU device templates

- - -
+
+
+

IOU device templates

+ +
- -
-
- -
- {{template.name}} - - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + + +
+
+
- - + diff --git a/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.spec.ts b/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.spec.ts index 1541fb77..9c8ebfd0 100644 --- a/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.spec.ts +++ b/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.spec.ts @@ -1,58 +1,64 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { IouTemplate } from '../../../../models/templates/iou-template'; -import { IouTemplatesComponent } from './iou-templates.component'; import { IouService } from '../../../../services/iou.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { IouTemplatesComponent } from './iou-templates.component'; export class MockedIouService { - public getTemplates(server: Server) { - return of([{} as IouTemplate]); - } + public getTemplates(server: Server) { + return of([{} as IouTemplate]); + } } describe('IouTemplatesComponent', () => { - let component: IouTemplatesComponent; - let fixture: ComponentFixture; + let component: IouTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedIouService = new MockedIouService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: IouService, useValue: mockedIouService } - ], - declarations: [ - IouTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedIouService = new MockedIouService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(IouTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: IouService, useValue: mockedIouService }, + ], + declarations: [IouTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(IouTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.ts b/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.ts index 4abb3203..9f140058 100644 --- a/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.ts +++ b/src/app/components/preferences/ios-on-unix/iou-templates/iou-templates.component.ts @@ -1,52 +1,51 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; +import { Server } from '../../../../models/server'; import { IouTemplate } from '../../../../models/templates/iou-template'; import { IouService } from '../../../../services/iou.service'; - +import { ServerService } from '../../../../services/server.service'; +import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ - selector: 'app-iou-templates', - templateUrl: './iou-templates.component.html', - styleUrls: ['./iou-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-iou-templates', + templateUrl: './iou-templates.component.html', + styleUrls: ['./iou-templates.component.scss', '../../preferences.component.scss'], }) export class IouTemplatesComponent implements OnInit { - server: Server; - iouTemplates: IouTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + iouTemplates: IouTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private iouService: IouService, - private router: Router - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private iouService: IouService, + private router: Router + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.iouService.getTemplates(this.server).subscribe((iouTemplates: IouTemplate[]) => { - this.iouTemplates = iouTemplates.filter((elem) => elem.template_type === 'iou' && !elem.builtin); - }); - } + getTemplates() { + this.iouService.getTemplates(this.server).subscribe((iouTemplates: IouTemplate[]) => { + this.iouTemplates = iouTemplates.filter((elem) => elem.template_type === 'iou' && !elem.builtin); + }); + } - deleteTemplate(template: IouTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: IouTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } - copyTemplate(template: IouTemplate) { - this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates', template.template_id, 'copy']); - } + copyTemplate(template: IouTemplate) { + this.router.navigate(['/server', this.server.id, 'preferences', 'iou', 'templates', template.template_id, 'copy']); + } } diff --git a/src/app/components/preferences/preferences.component.html b/src/app/components/preferences/preferences.component.html index f3000cf1..8ca23a4b 100644 --- a/src/app/components/preferences/preferences.component.html +++ b/src/app/components/preferences/preferences.component.html @@ -1,43 +1,25 @@
-
-
-

Preferences

-
+
+
+

Preferences

-
-
- - - GNS3 VM - - - Built-in - - - Dynamips - - - IOS on Unix - - - VPCS - - - QEMU - - - VirtualBox - - - VMware - - - Docker - - - -
+
+
diff --git a/src/app/components/preferences/preferences.component.scss b/src/app/components/preferences/preferences.component.scss index 1b12e960..4f0f84a4 100644 --- a/src/app/components/preferences/preferences.component.scss +++ b/src/app/components/preferences/preferences.component.scss @@ -1,99 +1,99 @@ .listcontainer { - padding-left: 0px!important; - padding-right: 0px!important; + padding-left: 0px !important; + padding-right: 0px !important; } .top-button { - height: 36px; - margin-top: 22px + height: 36px; + margin-top: 22px; } .choose-symbol-button { - height: 36px; - margin-top: 22px; + height: 36px; + margin-top: 22px; } .cancel-button { - height: 36px; - margin-top: 22px; - margin-right: 10px; + height: 36px; + margin-top: 22px; + margin-right: 10px; } .form-field { - width: 100%; + width: 100%; } .select { - width: 100%; + width: 100%; } .shadowed { - display: none; - transition: 0.25s; + display: none; + transition: 0.25s; } .nonvisible { - display: none; + display: none; } .configButton { - width: 100%; + width: 100%; } .configHideButton { - margin-left: 80%; - width: 20%; - margin-bottom: 10px; + margin-left: 80%; + width: 20%; + margin-bottom: 10px; } .symbolSelectionButton { - width: 100%; + width: 100%; } .list-item { - display: flex; + display: flex; } .template-name { - width: 95%; + width: 95%; } .delete-button { - width: 10%; - outline: none; + width: 10%; + outline: none; } .menu-button { - width: 5%; - outline: none!important; + width: 5%; + outline: none !important; } th { - border: 0px!important; + border: 0px !important; } th.mat-header-cell { - padding-bottom: 15px; + padding-bottom: 15px; } td.mat-cell { - padding-top: 15px; + padding-top: 15px; } .radio-button { - width: 50%; - padding-top: 20px; + width: 50%; + padding-top: 20px; } .radio-group { - margin-bottom: 20px; + margin-bottom: 20px; } .file-button { - width: 18%; + width: 18%; } .file-name-form-field { - padding-left: 2%; - width: 80%; + padding-left: 2%; + width: 80%; } diff --git a/src/app/components/preferences/preferences.component.spec.ts b/src/app/components/preferences/preferences.component.spec.ts index 9d88d062..690b0c0c 100644 --- a/src/app/components/preferences/preferences.component.spec.ts +++ b/src/app/components/preferences/preferences.component.spec.ts @@ -1,67 +1,74 @@ +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { PreferencesComponent } from './preferences.component'; import { ActivatedRoute } from '@angular/router'; -import { of } from 'rxjs'; -import { CommonModule } from '@angular/common'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RouterTestingModule } from '@angular/router/testing'; +import { of } from 'rxjs'; +import { PreferencesComponent } from './preferences.component'; export class MockedActivatedRoute { - get() { - return { - params: of({ id: 3 }), - snapshot: { - parent: { - params: { - id: 1 - } - }, - paramMap: { - get(name: string): string { - return '1'; - } - } - }, - }; - } + get() { + return { + params: of({ id: 3 }), + snapshot: { + parent: { + params: { + id: 1, + }, + }, + paramMap: { + get(name: string): string { + return '1'; + }, + }, + }, + }; + } } describe('PreferencesComponent', () => { - let component: PreferencesComponent; - let fixture: ComponentFixture; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - } - ], - declarations: [ - PreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(PreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); + let component: PreferencesComponent; + let fixture: ComponentFixture; + let activatedRoute = new MockedActivatedRoute().get(); - it('should save correct server id', () => { - expect(component.serverId).toBe('1'); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + ], + declarations: [PreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should save correct server id', () => { + expect(component.serverId).toBe('1'); + }); }); diff --git a/src/app/components/preferences/preferences.component.ts b/src/app/components/preferences/preferences.component.ts index 78ecb2f8..42de52ba 100644 --- a/src/app/components/preferences/preferences.component.ts +++ b/src/app/components/preferences/preferences.component.ts @@ -1,20 +1,17 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; - @Component({ - selector: 'app-preferences', - templateUrl: './preferences.component.html', - styleUrls: ['./preferences.component.scss'] + selector: 'app-preferences', + templateUrl: './preferences.component.html', + styleUrls: ['./preferences.component.scss'], }) export class PreferencesComponent implements OnInit { - public serverId: string = ""; + public serverId: string = ''; - constructor( - private route: ActivatedRoute - ) {} + constructor(private route: ActivatedRoute) {} - ngOnInit() { - this.serverId = this.route.snapshot.paramMap.get("server_id"); - } + ngOnInit() { + this.serverId = this.route.snapshot.paramMap.get('server_id'); + } } diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html index fa33755f..3620769c 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html @@ -1,108 +1,123 @@
-
-
-

New QEMU VM template

-
+
+
+

New QEMU VM template

-
-
- - - - Run this QEMU VM locally - Run this QEMU VM on the GNS3 VM - - +
+
+
+ + + + Run this QEMU VM locally + Run this QEMU VM on the GNS3 VM + + - -
- - -
-
-
+ +
+ +
+
+
- -
- - - - {{binary.path}} - - -
- - - MB - -
-
+ +
+ + + + {{ binary.path }} + +
+ + + MB + +
+
- - - - - {{type}} - - - - + + + + + {{ type }} + + + + - -
- - Existing image - New image -

- - - {{image.filename}} - - -
- - - - - -
-
-
-
-
-
- - -
+ +
+ + Existing image + New image

+ + + {{ image.filename }} + + +
+ + + + + +
+
+
+
+
+ + +
+
diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts index c075c4bb..3e192746 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts @@ -1,4 +1,7 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -8,149 +11,146 @@ import { MatMenuModule } from '@angular/material/menu'; import { MatSelectModule } from '@angular/material/select'; import { MatStepperModule } from '@angular/material/stepper'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute, Router } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; +import { QemuTemplate } from '../../../../models/templates/qemu-template'; +import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; +import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { QemuTemplate } from '../../../../models/templates/qemu-template'; import { AddQemuVmTemplateComponent } from './add-qemu-vm-template.component'; -import { QemuService } from '../../../../services/qemu.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; export class MockedQemuService { - public addTemplate(server: Server, qemuTemplate: QemuTemplate) { - return of(qemuTemplate); - } + public addTemplate(server: Server, qemuTemplate: QemuTemplate) { + return of(qemuTemplate); + } - public getBinaries(server: Server) { - return of([]); - } + public getBinaries(server: Server) { + return of([]); + } - public getImages(server: Server) { - return of([]); - } + public getImages(server: Server) { + return of([]); + } } //Tests disabled due to instability xdescribe('AddQemuVmTemplateComponent', () => { - let component: AddQemuVmTemplateComponent; - let fixture: ComponentFixture; + let component: AddQemuVmTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedQemuService = new MockedQemuService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - let router = { - navigate: jasmine.createSpy('navigate') + let mockedServerService = new MockedServerService(); + let mockedQemuService = new MockedQemuService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); + let router = { + navigate: jasmine.createSpy('navigate'), + }; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatStepperModule, + FormsModule, + ReactiveFormsModule, + MatSelectModule, + MatAutocompleteModule, + MatIconModule, + MatFormFieldModule, + MatInputModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/qemu/templates', component: AddQemuVmTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: Router, useValue: router }, + { provide: ServerService, useValue: mockedServerService }, + { provide: QemuService, useValue: mockedQemuService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + { provide: QemuConfigurationService, useClass: QemuConfigurationService }, + ], + declarations: [AddQemuVmTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddQemuVmTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should call add template', () => { + spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); + component.nameForm.controls['templateName'].setValue('template name'); + component.memoryForm.controls['binary'].setValue('binary'); + component.memoryForm.controls['ramMemory'].setValue(0); + component.diskForm.controls['fileName'].setValue('file name'); + component.chosenImage = 'path'; + component.selectedBinary = { + path: 'path', + version: 'version', }; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - MatStepperModule, - FormsModule, - ReactiveFormsModule, - MatSelectModule, - MatAutocompleteModule, - MatIconModule, - MatFormFieldModule, - MatInputModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/qemu/templates', component: AddQemuVmTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: Router, useValue: router }, - { provide: ServerService, useValue: mockedServerService }, - { provide: QemuService, useValue: mockedQemuService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: TemplateMocksService, useClass: TemplateMocksService }, - { provide: QemuConfigurationService, useClass: QemuConfigurationService } - ], - declarations: [ - AddQemuVmTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + component.newImageSelected = true; + component.server = { id: 1 } as Server; - beforeEach(() => { - fixture = TestBed.createComponent(AddQemuVmTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + component.addTemplate(); - it('should create', () => { - expect(component).toBeTruthy(); - }); + expect(mockedQemuService.addTemplate).toHaveBeenCalled(); + }); - it('should call add template', () => { - spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); - component.nameForm.controls['templateName'].setValue('template name'); - component.memoryForm.controls['binary'].setValue('binary'); - component.memoryForm.controls['ramMemory'].setValue(0); - component.diskForm.controls['fileName'].setValue('file name'); - component.chosenImage = 'path'; - component.selectedBinary = { - path: 'path', - version: 'version' - }; - component.newImageSelected = true; - component.server = {id: 1} as Server; + it('should not call add template when template name is empty', () => { + spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); + component.nameForm.controls['templateName'].setValue(''); + component.memoryForm.controls['binary'].setValue('binary'); + component.memoryForm.controls['ramMemory'].setValue(0); + component.diskForm.controls['fileName'].setValue('file name'); + component.chosenImage = 'path'; + component.selectedBinary = { + path: 'path', + version: 'version', + }; + component.newImageSelected = true; + component.server = { id: 1 } as Server; - component.addTemplate(); + component.addTemplate(); - expect(mockedQemuService.addTemplate).toHaveBeenCalled(); - }); + expect(mockedQemuService.addTemplate).not.toHaveBeenCalled(); + }); - it('should not call add template when template name is empty', () => { - spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); - component.nameForm.controls['templateName'].setValue(''); - component.memoryForm.controls['binary'].setValue('binary'); - component.memoryForm.controls['ramMemory'].setValue(0); - component.diskForm.controls['fileName'].setValue('file name'); - component.chosenImage = 'path'; - component.selectedBinary = { - path: 'path', - version: 'version' - }; - component.newImageSelected = true; - component.server = {id: 1} as Server; + it('should not call add template when ram is not set', () => { + spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); + component.nameForm.controls['templateName'].setValue('template name'); + component.memoryForm.controls['binary'].setValue('binary'); + component.diskForm.controls['fileName'].setValue('file name'); + component.chosenImage = 'path'; + component.selectedBinary = { + path: 'path', + version: 'version', + }; + component.newImageSelected = true; + component.server = { id: 1 } as Server; - component.addTemplate(); + component.addTemplate(); - expect(mockedQemuService.addTemplate).not.toHaveBeenCalled(); - }); - - it('should not call add template when ram is not set', () => { - spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); - component.nameForm.controls['templateName'].setValue('template name'); - component.memoryForm.controls['binary'].setValue('binary'); - component.diskForm.controls['fileName'].setValue('file name'); - component.chosenImage = 'path'; - component.selectedBinary = { - path: 'path', - version: 'version' - }; - component.newImageSelected = true; - component.server = {id: 1} as Server; - - component.addTemplate(); - - expect(mockedQemuService.addTemplate).not.toHaveBeenCalled(); - }); + expect(mockedQemuService.addTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts index 9d1f8583..739844fb 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts @@ -1,167 +1,166 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { QemuService } from '../../../../services/qemu.service'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload'; +import { v4 as uuid } from 'uuid'; +import { Compute } from '../../../../models/compute'; import { QemuBinary } from '../../../../models/qemu/qemu-binary'; import { QemuImage } from '../../../../models/qemu/qemu-image'; -import { ToasterService } from '../../../../services/toaster.service'; +import { Server } from '../../../../models/server'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; -import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; import { ComputeService } from '../../../../services/compute.service'; -import { Compute } from '../../../../models/compute'; -import { FileUploader, FileItem, ParsedResponseHeaders } from 'ng2-file-upload'; - +import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; +import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-add-qemu-virtual-machine-template', - templateUrl: './add-qemu-vm-template.component.html', - styleUrls: ['./add-qemu-vm-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-qemu-virtual-machine-template', + templateUrl: './add-qemu-vm-template.component.html', + styleUrls: ['./add-qemu-vm-template.component.scss', '../../preferences.component.scss'], }) export class AddQemuVmTemplateComponent implements OnInit { - server: Server; - qemuBinaries: QemuBinary[] = []; - selectedBinary: QemuBinary; - ramMemory: number; - consoleTypes: string[] = []; - newImageSelected: boolean = false;; - qemuImages: QemuImage[] = []; - selectedImage: QemuImage; - chosenImage: string = ''; - qemuTemplate: QemuTemplate; - uploader: FileUploader; + server: Server; + qemuBinaries: QemuBinary[] = []; + selectedBinary: QemuBinary; + ramMemory: number; + consoleTypes: string[] = []; + newImageSelected: boolean = false; + qemuImages: QemuImage[] = []; + selectedImage: QemuImage; + chosenImage: string = ''; + qemuTemplate: QemuTemplate; + uploader: FileUploader; - nameForm: FormGroup; - memoryForm: FormGroup; - diskForm: FormGroup; + nameForm: FormGroup; + memoryForm: FormGroup; + diskForm: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private qemuService: QemuService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder, - private templateMocksService: TemplateMocksService, - private configurationService: QemuConfigurationService, - private computeService: ComputeService - ) { - this.qemuTemplate = new QemuTemplate(); + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; - this.nameForm = this.formBuilder.group({ - templateName: new FormControl(null, Validators.required) - }); + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private qemuService: QemuService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder, + private templateMocksService: TemplateMocksService, + private configurationService: QemuConfigurationService, + private computeService: ComputeService + ) { + this.qemuTemplate = new QemuTemplate(); - this.memoryForm = this.formBuilder.group({ - ramMemory: new FormControl('256', Validators.required) - }); + this.nameForm = this.formBuilder.group({ + templateName: new FormControl(null, Validators.required), + }); - this.diskForm = this.formBuilder.group({ - fileName: new FormControl('', Validators.required) - }); + this.memoryForm = this.formBuilder.group({ + ramMemory: new FormControl('256', Validators.required), + }); + + this.diskForm = this.formBuilder.group({ + fileName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + this.uploader = new FileUploader({}); + this.uploader.onAfterAddingFile = (file) => { + file.withCredentials = false; + }; + this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { + this.toasterService.error('An error occured: ' + response); + }; + this.uploader.onSuccessItem = ( + item: FileItem, + response: string, + status: number, + headers: ParsedResponseHeaders + ) => { + this.qemuService.getImages(this.server).subscribe((qemuImages: QemuImage[]) => { + this.qemuImages = qemuImages; + }); + this.toasterService.success('Image uploaded'); + }; + + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.templateMocksService.getQemuTemplate().subscribe((qemuTemplate: QemuTemplate) => { + this.qemuTemplate = qemuTemplate; + }); + + this.qemuService.getBinaries(server).subscribe((qemuBinaries: QemuBinary[]) => { + this.qemuBinaries = qemuBinaries; + if (this.qemuBinaries[0]) this.selectedBinary = this.qemuBinaries[0]; + }); + + this.qemuService.getImages(server).subscribe((qemuImages: QemuImage[]) => { + this.qemuImages = qemuImages; + }); + + this.consoleTypes = this.configurationService.getConsoleTypes(); + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; } + } - ngOnInit() { - this.uploader = new FileUploader({}); - this.uploader.onAfterAddingFile = file => { - file.withCredentials = false; - }; - this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { - this.toasterService.error('An error occured: ' + response); - }; - this.uploader.onSuccessItem = ( - item: FileItem, - response: string, - status: number, - headers: ParsedResponseHeaders - ) => { - this.qemuService.getImages(this.server).subscribe((qemuImages: QemuImage[]) => { - this.qemuImages = qemuImages; - }); - this.toasterService.success('Image uploaded'); - }; - - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + setDiskImage(value: string) { + this.newImageSelected = value === 'newImage'; + } - this.templateMocksService.getQemuTemplate().subscribe((qemuTemplate: QemuTemplate) => { - this.qemuTemplate = qemuTemplate; - }) + uploadImageFile(event) { + let name = event.target.files[0].name; + this.diskForm.controls['fileName'].setValue(name); - this.qemuService.getBinaries(server).subscribe((qemuBinaries: QemuBinary[]) => { - this.qemuBinaries = qemuBinaries; - if (this.qemuBinaries[0]) this.selectedBinary = this.qemuBinaries[0]; - }); + const url = this.qemuService.getImagePath(this.server, name); + this.uploader.queue.forEach((elem) => (elem.url = url)); - this.qemuService.getImages(server).subscribe((qemuImages: QemuImage[]) => { - this.qemuImages = qemuImages; - }); + const itemToUpload = this.uploader.queue[0]; + if ((itemToUpload as any).options) (itemToUpload as any).options.disableMultipart = true; - this.consoleTypes = this.configurationService.getConsoleTypes(); + this.uploader.uploadItem(itemToUpload); + } - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - setDiskImage(value: string) { - this.newImageSelected = value === "newImage"; - } - - uploadImageFile(event) { - let name = event.target.files[0].name; - this.diskForm.controls['fileName'].setValue(name); - - const url = this.qemuService.getImagePath(this.server, name); - this.uploader.queue.forEach(elem => (elem.url = url)); - - const itemToUpload = this.uploader.queue[0]; - if ((itemToUpload as any).options) (itemToUpload as any).options.disableMultipart = true; - - this.uploader.uploadItem(itemToUpload); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); - } - - addTemplate() { - if (!this.nameForm.invalid && !this.memoryForm.invalid && (this.selectedImage || this.chosenImage)) { - this.qemuTemplate.ram = +this.memoryForm.get("ramMemory").value; - this.qemuTemplate.qemu_path = this.selectedBinary.path; - if (this.newImageSelected) { - this.qemuTemplate.hda_disk_image = this.diskForm.get("fileName").value; - } else { - this.qemuTemplate.hda_disk_image = this.selectedImage.path; - } - this.qemuTemplate.template_id = uuid(); - this.qemuTemplate.name = this.nameForm.get("templateName").value; - this.qemuTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - this.qemuService.addTemplate(this.server, this.qemuTemplate).subscribe((template: QemuTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + } + + addTemplate() { + if (!this.nameForm.invalid && !this.memoryForm.invalid && (this.selectedImage || this.chosenImage)) { + this.qemuTemplate.ram = +this.memoryForm.get('ramMemory').value; + this.qemuTemplate.qemu_path = this.selectedBinary.path; + if (this.newImageSelected) { + this.qemuTemplate.hda_disk_image = this.diskForm.get('fileName').value; + } else { + this.qemuTemplate.hda_disk_image = this.selectedImage.path; + } + this.qemuTemplate.template_id = uuid(); + this.qemuTemplate.name = this.nameForm.get('templateName').value; + this.qemuTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; + + this.qemuService.addTemplate(this.server, this.qemuTemplate).subscribe((template: QemuTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html index c1c8866d..6661ecaa 100644 --- a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html +++ b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html @@ -1,24 +1,20 @@
-
-
-

Copy QEMU VM template

-
+
+
+

Copy QEMU VM template

-
- -
- - - -
-
-
- - -
+
+
+ +
+ + + +
+
+
+ +
+
diff --git a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts index 2327f843..0c8eae00 100644 --- a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts +++ b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts @@ -1,68 +1,66 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { QemuService } from '../../../../services/qemu.service'; -import { QemuBinary } from '../../../../models/qemu/qemu-binary'; -import { ToasterService } from '../../../../services/toaster.service'; -import { QemuTemplate } from '../../../../models/templates/qemu-template'; import { v4 as uuid } from 'uuid'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { QemuBinary } from '../../../../models/qemu/qemu-binary'; +import { Server } from '../../../../models/server'; +import { QemuTemplate } from '../../../../models/templates/qemu-template'; +import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; @Component({ - selector: 'app-copy-qemu-virtual-machine-template', - templateUrl: './copy-qemu-vm-template.component.html', - styleUrls: ['./copy-qemu-vm-template.component.scss', '../../preferences.component.scss'] + selector: 'app-copy-qemu-virtual-machine-template', + templateUrl: './copy-qemu-vm-template.component.html', + styleUrls: ['./copy-qemu-vm-template.component.scss', '../../preferences.component.scss'], }) export class CopyQemuVmTemplateComponent implements OnInit { - server: Server; - qemuBinaries: QemuBinary[] = []; - templateName: string = ''; - qemuTemplate: QemuTemplate; - nameForm: FormGroup; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private qemuService: QemuService, - private toasterService: ToasterService, - private router: Router, - private formBuilder: FormBuilder - ) { - this.nameForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required) - }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.qemuService.getTemplate(this.server, template_id).subscribe((qemuTemplate: QemuTemplate) => { - this.qemuTemplate = qemuTemplate; - this.templateName = `Copy of ${this.qemuTemplate.name}`; - }) - - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); - } - - addTemplate() { - if (!this.nameForm.invalid) { - this.qemuTemplate.template_id = uuid(); - this.qemuTemplate.name = this.templateName; - - this.qemuService.addTemplate(this.server, this.qemuTemplate).subscribe((template: QemuTemplate) => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + server: Server; + qemuBinaries: QemuBinary[] = []; + templateName: string = ''; + qemuTemplate: QemuTemplate; + nameForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private qemuService: QemuService, + private toasterService: ToasterService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.nameForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.qemuService.getTemplate(this.server, template_id).subscribe((qemuTemplate: QemuTemplate) => { + this.qemuTemplate = qemuTemplate; + this.templateName = `Copy of ${this.qemuTemplate.name}`; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + } + + addTemplate() { + if (!this.nameForm.invalid) { + this.qemuTemplate.template_id = uuid(); + this.qemuTemplate.name = this.templateName; + + this.qemuService.addTemplate(this.server, this.qemuTemplate).subscribe((template: QemuTemplate) => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.html b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.html index 8c9f27ec..cfc27c66 100644 --- a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.html +++ b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.html @@ -1,29 +1,37 @@
-
-
-

QEMU preferences

- -
+
+
+

QEMU preferences

+ +
+
+
+
+ + + + Enable Hardware Acceleration (KVM/HAXM) + + + + + Require Hardware Acceleration (KVM/HAXM) + + +
-
-
- - - - Enable Hardware Acceleration (KVM/HAXM) - - - - - Require Hardware Acceleration (KVM/HAXM) - - - -
-
- - -
+
+ +
+
diff --git a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.scss b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.scss index 98f47574..36636d07 100644 --- a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.scss +++ b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.scss @@ -1,4 +1,4 @@ .top-button { - height: 36px; - margin-top: 22px + height: 36px; + margin-top: 22px; } diff --git a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.spec.ts b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.spec.ts index ea43ad2a..33a921c6 100644 --- a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.spec.ts +++ b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.spec.ts @@ -1,66 +1,74 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { HttpClientModule } from '@angular/common/http'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of } from 'rxjs'; +import { ServerSettingsService } from '../../../../services/server-settings.service'; +import { MockedServerSettingsService } from '../../../../services/server-settings.service.spec'; import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; import { QemuPreferencesComponent } from './qemu-preferences.component'; -import { ServerSettingsService } from '../../../../services/server-settings.service'; -import { HttpClientModule } from '@angular/common/http'; -import { MockedServerSettingsService } from '../../../../services/server-settings.service.spec'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { of } from 'rxjs'; describe('QemuPreferencesComponent', () => { - let component: QemuPreferencesComponent; - let fixture: ComponentFixture; + let component: QemuPreferencesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let activatedRoute = new MockedActivatedRoute().get(); - let mockedServerSettingsService = new MockedServerSettingsService(); - let mockedToasterService = new MockedToasterService(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [HttpClientModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: ServerSettingsService, useValue: mockedServerSettingsService }, - { provide: ToasterService, useValue: mockedToasterService } - ], - declarations: [ - QemuPreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let activatedRoute = new MockedActivatedRoute().get(); + let mockedServerSettingsService = new MockedServerSettingsService(); + let mockedToasterService = new MockedToasterService(); - beforeEach(() => { - fixture = TestBed.createComponent(QemuPreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: ServerSettingsService, useValue: mockedServerSettingsService }, + { provide: ToasterService, useValue: mockedToasterService }, + ], + declarations: [QemuPreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(QemuPreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call update settings when restore defaults chosen', () => { - spyOn(mockedServerSettingsService, 'updateSettingsForQemu').and.returnValue(of([])); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.restoreDefaults(); + it('should call update settings when restore defaults chosen', () => { + spyOn(mockedServerSettingsService, 'updateSettingsForQemu').and.returnValue(of([])); - expect(mockedServerSettingsService.updateSettingsForQemu).toHaveBeenCalled(); - }); + component.restoreDefaults(); + + expect(mockedServerSettingsService.updateSettingsForQemu).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.ts b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.ts index 68580110..8f3b6307 100644 --- a/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.ts +++ b/src/app/components/preferences/qemu/qemu-preferences/qemu-preferences.component.ts @@ -1,61 +1,61 @@ -import { Component, OnInit } from "@angular/core"; -import { ServerSettingsService } from '../../../../services/server-settings.service'; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; -import { switchMap } from 'rxjs/operators'; +import { QemuSettings } from '../../../../models/settings/qemu-settings'; +import { ServerSettingsService } from '../../../../services/server-settings.service'; import { ServerService } from '../../../../services/server.service'; import { ToasterService } from '../../../../services/toaster.service'; -import { QemuSettings } from '../../../../models/settings/qemu-settings'; - @Component({ - selector: 'app-qemu-preferences', - templateUrl: './qemu-preferences.component.html', - styleUrls: ['./qemu-preferences.component.scss'] + selector: 'app-qemu-preferences', + templateUrl: './qemu-preferences.component.html', + styleUrls: ['./qemu-preferences.component.scss'], }) export class QemuPreferencesComponent implements OnInit { - server: Server; - settings: QemuSettings; + server: Server; + settings: QemuSettings; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private serverSettingsService: ServerSettingsService, - private toasterService: ToasterService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private serverSettingsService: ServerSettingsService, + private toasterService: ToasterService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; - this.serverSettingsService.getSettingsForQemu(this.server).subscribe((settings: QemuSettings) => { - this.settings = settings; - }); - }); + this.serverSettingsService.getSettingsForQemu(this.server).subscribe((settings: QemuSettings) => { + this.settings = settings; + }); + }); + } + + apply() { + if (!this.settings.enable_hardware_acceleration) { + this.settings.require_hardware_acceleration = false; } - apply(){ - if(!this.settings.enable_hardware_acceleration){ - this.settings.require_hardware_acceleration = false; - } + this.serverSettingsService + .updateSettingsForQemu(this.server, this.settings) + .subscribe((qemuSettings: QemuSettings) => { + this.toasterService.success(`Changes applied`); + }); + } - this.serverSettingsService.updateSettingsForQemu(this.server, this.settings) - .subscribe((qemuSettings: QemuSettings) => { - this.toasterService.success(`Changes applied`); - }); - } + restoreDefaults() { + let defaultSettings: QemuSettings = { + enable_hardware_acceleration: true, + require_hardware_acceleration: true, + }; - restoreDefaults(){ - let defaultSettings : QemuSettings = { - enable_hardware_acceleration: true, - require_hardware_acceleration: true - }; - - this.serverSettingsService.updateSettingsForQemu(this.server, defaultSettings) - .subscribe((qemuSettings: QemuSettings) => { - this.settings = qemuSettings; - this.toasterService.success(`Restored to default settings`); - }); - } + this.serverSettingsService + .updateSettingsForQemu(this.server, defaultSettings) + .subscribe((qemuSettings: QemuSettings) => { + this.settings = qemuSettings; + this.toasterService.success(`Restored to default settings`); + }); + } } diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html index 23c88609..a53f2b4e 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html @@ -1,343 +1,305 @@ -
-
-
-

QEMU VM configuration

-
+
+
+
+

QEMU VM configuration

-
- - - - - General settings - - -
- - - - - - - - - -
-

- - - - {{category[0]}} - - - - - - MB - - - - - - - - {{binary.path}} - - - - - - - {{priority[0]}} - - - - - - - {{option[0]}} - - - - - - - {{type}} - - - - - Auto start console - -
- - - - HDD - - - - - - HDA (Primary Master) - - - - - - - - - {{interface}} - - - - - - - - - HDB (Primary Slave) - - - - - - - - - {{interface}} - - - - - - - - - HDC (Secondary Master) - - - - - - - - - {{interface}} - - - - - - - - - HDD (Secondary Slave) - - - - - - - - - {{interface}} - - - - - - - - - - CD/DVD - - -
- - - - - -
-
- - - - Network - - - - - - - - - - - - - - - - - - - - - {{type[1]}} ({{type[0]}}) - - - -
- - Use the legacy networking mode - -
- - - - Advanced - - - - - - Linux boot specific settings - - -
- - - - - -
-
- - - - - -
- - - -
-
- - - - Bios - - -
- - - - - -
-
-
- - - - Optimization - - - - Activate CPU throttling - - - - - - - - {{priority}} - - - - - - - - - Additional settings - - - - - - - Use as a linked base VM - - - -
- - - - Usage - - - - - - -
-
- - +
+
+ + + + General settings + +
+ + + + + + + + + +
+

+ + + + {{ category[0] }} + + + + + + MB + + + + + + + + {{ binary.path }} + + + + + + + {{ priority[0] }} + + + + + + + {{ option[0] }} + + + + + + + {{ type }} + + + + Auto start console +
+ + + HDD + + + + HDA (Primary Master) + + + + + + + + {{ interface }} + + + + + + + + HDB (Primary Slave) + + + + + + + + {{ interface }} + + + + + + + + HDC (Secondary Master) + + + + + + + + {{ interface }} + + + + + + + + HDD (Secondary Slave) + + + + + + + + {{ interface }} + + + + + + + + + CD/DVD + +
+ + + + +
+
+ + + Network + + + + + + + + + + + + + + + + + + + {{ type[1] }} ({{ type[0] }}) + + +
+ Use the legacy networking mode +
+ + + Advanced + + + + Linux boot specific settings + +
+ + + + + +
+
+ + + + + +
+ + + +
+
+ + + Bios + +
+ + + + + +
+
+
+ + + Optimization + + Activate CPU throttling + + + + + + + {{ priority }} + + + + + + + + Additional settings + + + + + Use as a linked base VM + + +
+ + + Usage + + + + + +
+
+ +
+
- - diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts index af687554..db001cb9 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts @@ -1,140 +1,148 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { AbstractControlDirective, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule, AbstractControlDirective, FormControl } from '@angular/forms'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; -import { QemuVmTemplateDetailsComponent } from './qemu-vm-template-details.component'; -import { QemuService } from '../../../../services/qemu.service'; import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; +import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { QemuVmTemplateDetailsComponent } from './qemu-vm-template-details.component'; export class MockedQemuService { - public getTemplate(server: Server, template_id: string) { - return of({} as QemuTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as QemuTemplate); + } - public saveTemplate(server: Server, qemuTemplate: QemuTemplate) { - return of(qemuTemplate); - } + public saveTemplate(server: Server, qemuTemplate: QemuTemplate) { + return of(qemuTemplate); + } - public getBinaries(server: Server) { - return of([]); - } + public getBinaries(server: Server) { + return of([]); + } - public getImages(server: Server) { - return of([]); - } + public getImages(server: Server) { + return of([]); + } } describe('QemuVmTemplateDetailsComponent', () => { - let component: QemuVmTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: QemuVmTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedQemuService = new MockedQemuService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatTableModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: QemuService, useValue: mockedQemuService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: QemuConfigurationService, useClass: QemuConfigurationService }, - { provide: AbstractControlDirective, useExisting: FormControl, useMulti: true } - ], - declarations: [ - QemuVmTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedQemuService = new MockedQemuService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(QemuVmTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: QemuService, useValue: mockedQemuService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: QemuConfigurationService, useClass: QemuConfigurationService }, + { provide: AbstractControlDirective, useExisting: FormControl, useMulti: true }, + ], + declarations: [QemuVmTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(QemuVmTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.qemuTemplate = { - adapters: 0, - custom_adapters: [] - } as QemuTemplate; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.qemuTemplate = { + adapters: 0, + custom_adapters: [], + } as QemuTemplate; - expect(mockedQemuService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when template name is empty', () => { - spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); - component.generalSettingsForm.controls['templateName'].setValue(''); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.qemuTemplate = { - adapters: 0, - custom_adapters: [] - } as QemuTemplate; + expect(mockedQemuService.saveTemplate).toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when template name is empty', () => { + spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); + component.generalSettingsForm.controls['templateName'].setValue(''); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.qemuTemplate = { + adapters: 0, + custom_adapters: [], + } as QemuTemplate; - expect(mockedQemuService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); + expect(mockedQemuService.saveTemplate).not.toHaveBeenCalled(); + }); - it('should not call save template when default name is empty', () => { - spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue(''); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.qemuTemplate = { - adapters: 0, - custom_adapters: [] - } as QemuTemplate; + it('should not call save template when default name is empty', () => { + spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue(''); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.qemuTemplate = { + adapters: 0, + custom_adapters: [], + } as QemuTemplate; - component.onSave(); + component.onSave(); - expect(mockedQemuService.saveTemplate).not.toHaveBeenCalled(); - }); + expect(mockedQemuService.saveTemplate).not.toHaveBeenCalled(); + }); - it('should call save template when symbol is empty', () => { - spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue(''); - component.qemuTemplate = { - adapters: 0, - custom_adapters: [] - } as QemuTemplate; + it('should call save template when symbol is empty', () => { + spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue(''); + component.qemuTemplate = { + adapters: 0, + custom_adapters: [], + } as QemuTemplate; - component.onSave(); + component.onSave(); - expect(mockedQemuService.saveTemplate).not.toHaveBeenCalled(); - }); + expect(mockedQemuService.saveTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts index 7fc7d285..4d7e1ff4 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts @@ -1,164 +1,163 @@ -import { Component, OnInit, ViewChildren, ViewChild, QueryList } from "@angular/core"; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { QemuService } from '../../../../services/qemu.service'; +import { QemuBinary } from '../../../../models/qemu/qemu-binary'; +import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; import { Server } from '../../../../models/server'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; -import { QemuBinary } from '../../../../models/qemu/qemu-binary'; -import { ToasterService } from '../../../../services/toaster.service'; -import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; -import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms'; +import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { CustomAdaptersComponent } from '../../common/custom-adapters/custom-adapters.component'; - @Component({ - selector: 'app-qemu-virtual-machine-template-details', - templateUrl: './qemu-vm-template-details.component.html', - styleUrls: ['./qemu-vm-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-qemu-virtual-machine-template-details', + templateUrl: './qemu-vm-template-details.component.html', + styleUrls: ['./qemu-vm-template-details.component.scss', '../../preferences.component.scss'], }) export class QemuVmTemplateDetailsComponent implements OnInit { - server: Server; - qemuTemplate: QemuTemplate; - isSymbolSelectionOpened: boolean = false; - consoleTypes: string[] = []; - diskInterfaces: string[] = []; - networkTypes = []; - bootPriorities = []; - onCloseOptions = []; - categories = []; - priorities: string[] = []; - binaries: QemuBinary[] = []; - activateCpuThrottling: boolean = true; - isConfiguratorOpened: boolean = false; - displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type', 'actions']; - generalSettingsForm: FormGroup; + server: Server; + qemuTemplate: QemuTemplate; + isSymbolSelectionOpened: boolean = false; + consoleTypes: string[] = []; + diskInterfaces: string[] = []; + networkTypes = []; + bootPriorities = []; + onCloseOptions = []; + categories = []; + priorities: string[] = []; + binaries: QemuBinary[] = []; + activateCpuThrottling: boolean = true; + isConfiguratorOpened: boolean = false; + displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type', 'actions']; + generalSettingsForm: FormGroup; - @ViewChild("customAdaptersConfigurator") - customAdaptersConfigurator: CustomAdaptersComponent; + @ViewChild('customAdaptersConfigurator') + customAdaptersConfigurator: CustomAdaptersComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private qemuService: QemuService, - private toasterService: ToasterService, - private configurationService: QemuConfigurationService, - private formBuilder: FormBuilder, - private router: Router - ){ - this.generalSettingsForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private qemuService: QemuService, + private toasterService: ToasterService, + private configurationService: QemuConfigurationService, + private formBuilder: FormBuilder, + private router: Router + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.qemuService.getTemplate(this.server, template_id).subscribe((qemuTemplate: QemuTemplate) => { + this.qemuTemplate = qemuTemplate; + this.fillCustomAdapters(); + + this.qemuService.getBinaries(server).subscribe((qemuBinaries: QemuBinary[]) => { + this.binaries = qemuBinaries; }); - } + }); + }); + } - ngOnInit(){ - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.getConfiguration(); - this.qemuService.getTemplate(this.server, template_id).subscribe((qemuTemplate: QemuTemplate) => { - this.qemuTemplate = qemuTemplate; - this.fillCustomAdapters(); + getConfiguration() { + this.consoleTypes = this.configurationService.getConsoleTypes(); + this.diskInterfaces = this.configurationService.getDiskInterfaces(); + this.networkTypes = this.configurationService.getNetworkTypes(); + this.bootPriorities = this.configurationService.getBootPriorities(); + this.onCloseOptions = this.configurationService.getOnCloseOptions(); + this.categories = this.configurationService.getCategories(); + this.priorities = this.configurationService.getPriorities(); + } - this.qemuService.getBinaries(server).subscribe((qemuBinaries: QemuBinary[]) => { - this.binaries = qemuBinaries; - }); - }); + uploadCdromImageFile(event) { + this.qemuTemplate.cdrom_image = event.target.files[0].name; + } + + uploadInitrdFile(event) { + this.qemuTemplate.initrd = event.target.files[0].name; + } + + uploadKernelImageFile(event) { + this.qemuTemplate.kernel_image = event.target.files[0].name; + } + + uploadBiosFile(event) { + this.qemuTemplate.bios_image = event.target.files[0].name; + } + + setCustomAdaptersConfiguratorState(state: boolean) { + this.isConfiguratorOpened = state; + + if (state) { + this.fillCustomAdapters(); + this.customAdaptersConfigurator.numberOfAdapters = this.qemuTemplate.adapters; + this.customAdaptersConfigurator.adapters = []; + this.qemuTemplate.custom_adapters.forEach((adapter: CustomAdapter) => { + this.customAdaptersConfigurator.adapters.push({ + adapter_number: adapter.adapter_number, + adapter_type: adapter.adapter_type, }); + }); } + } - getConfiguration(){ - this.consoleTypes = this.configurationService.getConsoleTypes(); - this.diskInterfaces = this.configurationService.getDiskInterfaces(); - this.networkTypes = this.configurationService.getNetworkTypes(); - this.bootPriorities = this.configurationService.getBootPriorities(); - this.onCloseOptions = this.configurationService.getOnCloseOptions(); - this.categories = this.configurationService.getCategories(); - this.priorities = this.configurationService.getPriorities(); + saveCustomAdapters(adapters: CustomAdapter[]) { + this.setCustomAdaptersConfiguratorState(false); + this.qemuTemplate.custom_adapters = adapters; + } + + fillCustomAdapters() { + let copyOfAdapters = this.qemuTemplate.custom_adapters ? this.qemuTemplate.custom_adapters : []; + this.qemuTemplate.custom_adapters = []; + + for (let i = 0; i < this.qemuTemplate.adapters; i++) { + if (copyOfAdapters[i]) { + this.qemuTemplate.custom_adapters.push(copyOfAdapters[i]); + } else { + this.qemuTemplate.custom_adapters.push({ + adapter_number: i, + adapter_type: 'e1000', + }); + } } + } - uploadCdromImageFile(event){ - this.qemuTemplate.cdrom_image = event.target.files[0].name; + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + } + + onSave() { + if (this.generalSettingsForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + if (!this.activateCpuThrottling) { + this.qemuTemplate.cpu_throttling = 0; + } + this.fillCustomAdapters(); + + this.qemuService.saveTemplate(this.server, this.qemuTemplate).subscribe((savedTemplate: QemuTemplate) => { + this.toasterService.success('Changes saved'); + }); } + } - uploadInitrdFile(event){ - this.qemuTemplate.initrd = event.target.files[0].name; - } + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - uploadKernelImageFile(event){ - this.qemuTemplate.kernel_image = event.target.files[0].name; - } - - uploadBiosFile(event){ - this.qemuTemplate.bios_image = event.target.files[0].name; - } - - setCustomAdaptersConfiguratorState(state: boolean) { - this.isConfiguratorOpened = state; - - if (state) { - this.fillCustomAdapters(); - this.customAdaptersConfigurator.numberOfAdapters = this.qemuTemplate.adapters; - this.customAdaptersConfigurator.adapters = []; - this.qemuTemplate.custom_adapters.forEach((adapter: CustomAdapter) => { - this.customAdaptersConfigurator.adapters.push({ - adapter_number: adapter.adapter_number, - adapter_type: adapter.adapter_type - }); - }); - } - } - - saveCustomAdapters(adapters: CustomAdapter[]){ - this.setCustomAdaptersConfiguratorState(false); - this.qemuTemplate.custom_adapters = adapters; - } - - fillCustomAdapters() { - let copyOfAdapters = this.qemuTemplate.custom_adapters ? this.qemuTemplate.custom_adapters : []; - this.qemuTemplate.custom_adapters = []; - - for(let i=0; i { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.qemuTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.qemuTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html index cf79bba7..98e610e0 100644 --- a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html +++ b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html @@ -1,35 +1,49 @@
-
-
-

QEMU VM templates

- - -
+
+
+

QEMU VM templates

+ +
- -
-
- -
- {{template.name}} - - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + + +
+
+
- - + diff --git a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.spec.ts b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.spec.ts index 0a16c4f2..a21a8006 100644 --- a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.spec.ts +++ b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; -import { QemuVmTemplatesComponent } from './qemu-vm-templates.component'; import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { QemuVmTemplatesComponent } from './qemu-vm-templates.component'; export class MockedQemuService { - public getTemplates(server: Server) { - return of([{} as QemuTemplate]); - } + public getTemplates(server: Server) { + return of([{} as QemuTemplate]); + } } describe('QemuTemplatesComponent', () => { - let component: QemuVmTemplatesComponent; - let fixture: ComponentFixture; + let component: QemuVmTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedQemuService = new MockedQemuService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: QemuService, useValue: mockedQemuService } - ], - declarations: [ - QemuVmTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedQemuService = new MockedQemuService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(QemuVmTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: QemuService, useValue: mockedQemuService }, + ], + declarations: [QemuVmTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(QemuVmTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts index cadc97e8..f5c08011 100644 --- a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts +++ b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts @@ -1,52 +1,51 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; +import { Server } from '../../../../models/server'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; import { QemuService } from '../../../../services/qemu.service'; +import { ServerService } from '../../../../services/server.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; - @Component({ - selector: 'app-qemu-virtual-machines-templates', - templateUrl: './qemu-vm-templates.component.html', - styleUrls: ['./qemu-vm-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-qemu-virtual-machines-templates', + templateUrl: './qemu-vm-templates.component.html', + styleUrls: ['./qemu-vm-templates.component.scss', '../../preferences.component.scss'], }) export class QemuVmTemplatesComponent implements OnInit { - server: Server; - qemuTemplates: QemuTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + qemuTemplates: QemuTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private qemuService: QemuService, - private router: Router - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private qemuService: QemuService, + private router: Router + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.qemuService.getTemplates(this.server).subscribe((qemuTemplates: QemuTemplate[]) => { - this.qemuTemplates = qemuTemplates.filter((elem) => elem.template_type === 'qemu' && !elem.builtin); - }); - } + getTemplates() { + this.qemuService.getTemplates(this.server).subscribe((qemuTemplates: QemuTemplate[]) => { + this.qemuTemplates = qemuTemplates.filter((elem) => elem.template_type === 'qemu' && !elem.builtin); + }); + } - deleteTemplate(template: QemuTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: QemuTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } - copyTemplate(template: QemuTemplate) { - this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates', template.template_id, 'copy']); - } + copyTemplate(template: QemuTemplate) { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates', template.template_id, 'copy']); + } } diff --git a/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.html b/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.html index 96359baa..4c7a9b2e 100644 --- a/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.html +++ b/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.html @@ -1,23 +1,23 @@
-
-
-

New VPCS node template

-
+
+
+

New VPCS node template

-
- -
- - - - - - -
-
-
- - -
+
+
+ +
+ + + + + + +
+
+
+ +
+
diff --git a/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.ts b/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.ts index 70fd2a10..a48a0a72 100644 --- a/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.ts +++ b/src/app/components/preferences/traceng/add-traceng/add-traceng-template.component.ts @@ -1,67 +1,66 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; -import { TracengService } from '../../../../services/traceng.service'; +import { Server } from '../../../../models/server'; import { TracengTemplate } from '../../../../models/templates/traceng-template'; - +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { TracengService } from '../../../../services/traceng.service'; @Component({ - selector: 'app-add-traceng-template', - templateUrl: './add-traceng-template.component.html', - styleUrls: ['./add-traceng-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-traceng-template', + templateUrl: './add-traceng-template.component.html', + styleUrls: ['./add-traceng-template.component.scss', '../../preferences.component.scss'], }) export class AddTracengTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - ipAddress: string = ''; - templateNameForm: FormGroup - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private tracengService: TracengService, - private router: Router, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private formBuilder: FormBuilder - ) { - this.templateNameForm = this.formBuilder.group({ - templateName: new FormControl(null, [Validators.required]), - ipAddress: new FormControl(null, [Validators.required]) - }); - } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'traceng', 'templates']); - } - - addTemplate() { - if (!this.templateNameForm.invalid) { - this.templateName = this.templateNameForm.get('templateName').value; - this.ipAddress = this.templateNameForm.get('ipAddress').value; - let tracengTemplate: TracengTemplate = this.templateMocksService.getTracengTemplate(); - - tracengTemplate.template_id = uuid(); - tracengTemplate.name = this.templateName; - tracengTemplate.ip_address = this.ipAddress; - - this.tracengService.addTemplate(this.server, tracengTemplate).subscribe(() => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + server: Server; + templateName: string = ''; + ipAddress: string = ''; + templateNameForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private tracengService: TracengService, + private router: Router, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl(null, [Validators.required]), + ipAddress: new FormControl(null, [Validators.required]), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'traceng', 'templates']); + } + + addTemplate() { + if (!this.templateNameForm.invalid) { + this.templateName = this.templateNameForm.get('templateName').value; + this.ipAddress = this.templateNameForm.get('ipAddress').value; + let tracengTemplate: TracengTemplate = this.templateMocksService.getTracengTemplate(); + + tracengTemplate.template_id = uuid(); + tracengTemplate.name = this.templateName; + tracengTemplate.ip_address = this.ipAddress; + + this.tracengService.addTemplate(this.server, tracengTemplate).subscribe(() => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.html b/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.html index 4e94dbb2..20b26241 100644 --- a/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.html +++ b/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.html @@ -1,12 +1,12 @@
-
-
-

TraceNG preferences

-
-
-
- - - +
+
+

TraceNG preferences

+
+
+ + + +
diff --git a/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.scss b/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.scss index 9c2173c2..8aff6f5a 100644 --- a/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.scss +++ b/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.scss @@ -1,3 +1,3 @@ .form-field { - width: 100%; + width: 100%; } diff --git a/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.ts b/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.ts index a698d8af..d33bb9ea 100644 --- a/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.ts +++ b/src/app/components/preferences/traceng/traceng-preferences/traceng-preferences.component.ts @@ -1,32 +1,28 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; import { ServerService } from '../../../../services/server.service'; - @Component({ - selector: 'app-traceng-preferences', - templateUrl: './traceng-preferences.component.html', - styleUrls: ['./traceng-preferences.component.scss'] + selector: 'app-traceng-preferences', + templateUrl: './traceng-preferences.component.html', + styleUrls: ['./traceng-preferences.component.scss'], }) export class TracengPreferencesComponent implements OnInit { - server: Server; - tracengExecutable: string; + server: Server; + tracengExecutable: string; - constructor( - private route: ActivatedRoute, - private serverService: ServerService - ) {} + constructor(private route: ActivatedRoute, private serverService: ServerService) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - }); - } + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + }); + } - restoreDefaults(){ - this.tracengExecutable = ''; - } + restoreDefaults() { + this.tracengExecutable = ''; + } } diff --git a/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.html b/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.html index 01e1acdc..2bd43929 100644 --- a/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.html +++ b/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.html @@ -1,40 +1,51 @@
-
-
-

TraceNG device configuration

-
+
+
+

TraceNG device configuration

-
- -
- - - - - - - - - -

-
-
-
- - -
+
+
+ +
+ + + + + + + + + +

+
+
+
+ +
+
- + diff --git a/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.ts b/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.ts index 3042bfce..dd56acee 100644 --- a/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.ts +++ b/src/app/components/preferences/traceng/traceng-template-details/traceng-template-details.component.ts @@ -1,71 +1,72 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; -import { TracengService } from '../../../../services/traceng.service'; import { TracengTemplate } from '../../../../models/templates/traceng-template'; - +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { TracengService } from '../../../../services/traceng.service'; @Component({ - selector: 'app-traceng-template-details', - templateUrl: './traceng-template-details.component.html', - styleUrls: ['./traceng-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-traceng-template-details', + templateUrl: './traceng-template-details.component.html', + styleUrls: ['./traceng-template-details.component.scss', '../../preferences.component.scss'], }) export class TracengTemplateDetailsComponent implements OnInit { - server: Server; - tracengTemplate: TracengTemplate; - inputForm: FormGroup; - isSymbolSelectionOpened: boolean = false; + server: Server; + tracengTemplate: TracengTemplate; + inputForm: FormGroup; + isSymbolSelectionOpened: boolean = false; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private tracengService: TracengService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private router: Router - ) { - this.inputForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private tracengService: TracengService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private router: Router + ) { + this.inputForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.tracengService.getTemplate(this.server, template_id).subscribe((tracengTemplate: TracengTemplate) => { + this.tracengTemplate = tracengTemplate; + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'traceng', 'templates']); + } + + onSave() { + if (this.inputForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.tracengService + .saveTemplate(this.server, this.tracengTemplate) + .subscribe((tracengTemplate: TracengTemplate) => { + this.toasterService.success('Changes saved'); }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - this.tracengService.getTemplate(this.server, template_id).subscribe((tracengTemplate: TracengTemplate) => { - this.tracengTemplate = tracengTemplate; - }); - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'traceng', 'templates']); - } - - onSave() { - if (this.inputForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.tracengService.saveTemplate(this.server, this.tracengTemplate).subscribe((tracengTemplate: TracengTemplate) => { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.tracengTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.tracengTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.html b/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.html index af922d9f..0932bb84 100644 --- a/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.html +++ b/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.html @@ -1,32 +1,46 @@
-
-
-

TraceNG node templates

- - -
+
+
+

TraceNG node templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.ts b/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.ts index ad7ef307..798229ca 100644 --- a/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.ts +++ b/src/app/components/preferences/traceng/traceng-templates/traceng-templates.component.ts @@ -1,46 +1,46 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; +import { Server } from '../../../../models/server'; import { TracengTemplate } from '../../../../models/templates/traceng-template'; +import { ServerService } from '../../../../services/server.service'; import { TracengService } from '../../../../services/traceng.service'; +import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ - selector: 'app-traceng-templates', - templateUrl: './traceng-templates.component.html', - styleUrls: ['./traceng-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-traceng-templates', + templateUrl: './traceng-templates.component.html', + styleUrls: ['./traceng-templates.component.scss', '../../preferences.component.scss'], }) export class TracengTemplatesComponent implements OnInit { - server: Server; - tracengTemplates: TracengTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + tracengTemplates: TracengTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private tracengService: TracengService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private tracengService: TracengService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.tracengService.getTemplates(this.server).subscribe((tracengTemplates: TracengTemplate[]) => { - this.tracengTemplates = tracengTemplates.filter((elem) => elem.template_type === 'traceng' && !elem.builtin); - }); - } + getTemplates() { + this.tracengService.getTemplates(this.server).subscribe((tracengTemplates: TracengTemplate[]) => { + this.tracengTemplates = tracengTemplates.filter((elem) => elem.template_type === 'traceng' && !elem.builtin); + }); + } - deleteTemplate(template: TracengTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: TracengTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html index ca621a17..9e53678d 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html @@ -1,30 +1,27 @@
-
-
-

New VirtualBox VM template

-
+
+
+

New VirtualBox VM template

-
- -
- - - - {{vm.vmname}} - - - -
- - Use as a linked base VM (experimental) - -
-
- - -
+
+
+ +
+ + + + {{ vm.vmname }} + + + +
+ + Use as a linked base VM (experimental) + +
+
+ +
+
diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts index dd55daf8..3dde837f 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts @@ -1,125 +1,125 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; -import { AddVirtualBoxTemplateComponent } from './add-virtual-box-template.component'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { AddVirtualBoxTemplateComponent } from './add-virtual-box-template.component'; export class MockedVirtualBoxService { - public addTemplate(server: Server, virtualBoxTemplate: VirtualBoxTemplate) { - return of(virtualBoxTemplate); - } + public addTemplate(server: Server, virtualBoxTemplate: VirtualBoxTemplate) { + return of(virtualBoxTemplate); + } - public getVirtualMachines(server: Server) { - return of([]); - } + public getVirtualMachines(server: Server) { + return of([]); + } } describe('AddVirtualBoxTemplateComponent', () => { - let component: AddVirtualBoxTemplateComponent; - let fixture: ComponentFixture; + let component: AddVirtualBoxTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVirtualBoxService = new MockedVirtualBoxService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/virtualbox/templates', component: AddVirtualBoxTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VirtualBoxService, useValue: mockedVirtualBoxService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: TemplateMocksService, useClass: TemplateMocksService } - ], - declarations: [ - AddVirtualBoxTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVirtualBoxService = new MockedVirtualBoxService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(AddVirtualBoxTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/virtualbox/templates', component: AddVirtualBoxTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VirtualBoxService, useValue: mockedVirtualBoxService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + ], + declarations: [AddVirtualBoxTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AddVirtualBoxTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedVirtualBoxService, 'addTemplate').and.returnValue(of({} as VirtualBoxTemplate)); - let template: VirtualBoxTemplate = { - adapter_type: 'Intel PRO/1000 MT Desktop (82540EM)', - adapters: 1, - builtin: false, - category: 'guest', - compute_id: 'local', - console_auto_start: false, - console_type: 'none', - custom_adapters: [], - default_name_format: '{name}-{0}', - first_port_name: '', - headless: false, - linked_clone: false, - name: '', - on_close: 'power_off', - port_name_format: 'Ethernet{0}', - port_segment_size: 0, - ram: 0, - symbol: ':/symbols/vbox_guest.svg', - template_id: '', - template_type: 'virtualbox', - usage: '', - use_any_adapter: false, - vmname: '' - } - component.virtualBoxTemplate = {} as VirtualBoxTemplate; - component.selectedVM = template; - component.server = {id: 1} as Server; - component.vmForm.controls['vm'].setValue('virtual machine'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call save template', () => { + spyOn(mockedVirtualBoxService, 'addTemplate').and.returnValue(of({} as VirtualBoxTemplate)); + let template: VirtualBoxTemplate = { + adapter_type: 'Intel PRO/1000 MT Desktop (82540EM)', + adapters: 1, + builtin: false, + category: 'guest', + compute_id: 'local', + console_auto_start: false, + console_type: 'none', + custom_adapters: [], + default_name_format: '{name}-{0}', + first_port_name: '', + headless: false, + linked_clone: false, + name: '', + on_close: 'power_off', + port_name_format: 'Ethernet{0}', + port_segment_size: 0, + ram: 0, + symbol: ':/symbols/vbox_guest.svg', + template_id: '', + template_type: 'virtualbox', + usage: '', + use_any_adapter: false, + vmname: '', + }; + component.virtualBoxTemplate = {} as VirtualBoxTemplate; + component.selectedVM = template; + component.server = { id: 1 } as Server; + component.vmForm.controls['vm'].setValue('virtual machine'); - expect(mockedVirtualBoxService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call save template when virtual machine is not selected', () => { - spyOn(mockedVirtualBoxService, 'addTemplate').and.returnValue(of({} as VirtualBoxTemplate)); - component.server = {id: 1} as Server; + expect(mockedVirtualBoxService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call save template when virtual machine is not selected', () => { + spyOn(mockedVirtualBoxService, 'addTemplate').and.returnValue(of({} as VirtualBoxTemplate)); + component.server = { id: 1 } as Server; - expect(mockedVirtualBoxService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedVirtualBoxService.addTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts index aa48d497..06108e20 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts @@ -1,73 +1,72 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { VirtualBoxService } from '../../../../services/virtual-box.service'; -import { VirtualBoxVm } from '../../../../models/virtualBox/virtual-box-vm'; -import { ToasterService } from '../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; import { v4 as uuid } from 'uuid'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - +import { Server } from '../../../../models/server'; +import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; +import { VirtualBoxVm } from '../../../../models/virtualBox/virtual-box-vm'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { VirtualBoxService } from '../../../../services/virtual-box.service'; @Component({ - selector: 'app-add-virtual-box-template', - templateUrl: './add-virtual-box-template.component.html', - styleUrls: ['./add-virtual-box-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-virtual-box-template', + templateUrl: './add-virtual-box-template.component.html', + styleUrls: ['./add-virtual-box-template.component.scss', '../../preferences.component.scss'], }) export class AddVirtualBoxTemplateComponent implements OnInit { - server: Server; - virtualMachines: VirtualBoxVm[]; - selectedVM: VirtualBoxVm; - virtualBoxTemplate: VirtualBoxTemplate; - vmForm: FormGroup; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private virtualBoxService: VirtualBoxService, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private router: Router, - private formBuilder: FormBuilder - ) { - this.vmForm = this.formBuilder.group({ - vm: new FormControl('', Validators.required) + server: Server; + virtualMachines: VirtualBoxVm[]; + selectedVM: VirtualBoxVm; + virtualBoxTemplate: VirtualBoxTemplate; + vmForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private virtualBoxService: VirtualBoxService, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.vmForm = this.formBuilder.group({ + vm: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.virtualBoxService.getVirtualMachines(this.server).subscribe((virtualMachines: VirtualBoxVm[]) => { + this.virtualMachines = virtualMachines; + + this.templateMocksService.getVirtualBoxTemplate().subscribe((template: VirtualBoxTemplate) => { + this.virtualBoxTemplate = template; }); + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'virtualbox', 'templates']); + } + + addTemplate() { + if (!this.vmForm.invalid) { + this.virtualBoxTemplate.name = this.selectedVM.vmname; + this.virtualBoxTemplate.vmname = this.selectedVM.vmname; + this.virtualBoxTemplate.ram = this.selectedVM.ram; + this.virtualBoxTemplate.template_id = uuid(); + + this.virtualBoxService.addTemplate(this.server, this.virtualBoxTemplate).subscribe(() => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.virtualBoxService.getVirtualMachines(this.server).subscribe((virtualMachines: VirtualBoxVm[]) => { - this.virtualMachines = virtualMachines; - - this.templateMocksService.getVirtualBoxTemplate().subscribe((template: VirtualBoxTemplate) => { - this.virtualBoxTemplate = template; - }); - }) - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'virtualbox', 'templates']); - } - - addTemplate() { - if (!this.vmForm.invalid) { - this.virtualBoxTemplate.name = this.selectedVM.vmname; - this.virtualBoxTemplate.vmname = this.selectedVM.vmname; - this.virtualBoxTemplate.ram = this.selectedVM.ram; - this.virtualBoxTemplate.template_id = uuid(); - - this.virtualBoxService.addTemplate(this.server, this.virtualBoxTemplate).subscribe(() => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } - } + } } diff --git a/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.html b/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.html index a5e28de9..5933408b 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.html +++ b/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.html @@ -1,12 +1,12 @@
-
-
-

VirtualBox preferences

-
-
-
- - - +
+
+

VirtualBox preferences

+
+
+ + + +
diff --git a/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.ts b/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.ts index 7fe26828..3041f9f4 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component.ts @@ -1,32 +1,27 @@ -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; -import { switchMap } from 'rxjs/operators'; import { ServerService } from '../../../../services/server.service'; - @Component({ - selector: 'app-virtual-box-preferences', - templateUrl: './virtual-box-preferences.component.html', - styleUrls: ['./virtual-box-preferences.component.scss'] + selector: 'app-virtual-box-preferences', + templateUrl: './virtual-box-preferences.component.html', + styleUrls: ['./virtual-box-preferences.component.scss'], }) export class VirtualBoxPreferencesComponent implements OnInit { - server: Server; - vboxManagePath: string; + server: Server; + vboxManagePath: string; - constructor( - private route: ActivatedRoute, - private serverService: ServerService - ) {} + constructor(private route: ActivatedRoute, private serverService: ServerService) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + }); + } - restoreDefaults(){ - this.vboxManagePath = ''; - } + restoreDefaults() { + this.vboxManagePath = ''; + } } diff --git a/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-prefernces.component.spec.ts b/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-prefernces.component.spec.ts index 1529e7de..1a1f8289 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-prefernces.component.spec.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-preferences/virtual-box-prefernces.component.spec.ts @@ -1,54 +1,61 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; +import { RouterTestingModule } from '@angular/router/testing'; import { ServerService } from '../../../../services/server.service'; -import { VirtualBoxPreferencesComponent } from './virtual-box-preferences.component'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VirtualBoxPreferencesComponent } from './virtual-box-preferences.component'; describe('VirtualBoxPreferencesComponent', () => { - let component: VirtualBoxPreferencesComponent; - let fixture: ComponentFixture; + let component: VirtualBoxPreferencesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService } - ], - declarations: [ - VirtualBoxPreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VirtualBoxPreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + ], + declarations: [VirtualBoxPreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VirtualBoxPreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should clear path to virtual box manage', () => { - component.restoreDefaults(); + it('should create', () => { + expect(component).toBeTruthy(); + }); - expect(component.vboxManagePath).toBe(''); - }); + it('should clear path to virtual box manage', () => { + component.restoreDefaults(); + + expect(component.vboxManagePath).toBe(''); + }); }); diff --git a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html index 4b19c3d8..7f0f6e19 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html +++ b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html @@ -1,124 +1,182 @@
-
-
-

VirtualBox VM configuration

-
+
+
+

VirtualBox VM configuration

-
- - - - - General settings - - -
- - - - - - - - - -

- - - - {{category[0]}} - - - - - - - {{type}} - - - - - Auto start console - - - - MB - - - - - {{option[0]}} - - - -
- - Start VM in headless mode -
- - Use as a linked base VM (experimental) - -
- - - - Network - - -
- - - - - - - - - - - - - - - - {{type}} - - - -
-
- - Allow GNS3 to use any configured VirtualBox adapter - -
- - - - Usage - - - - - - -
-
- - -
+
+
+ + + + General settings + +
+ + + + + + + + + +

+ + + + {{ category[0] }} + + + + + + + {{ type }} + + + + + Auto start console + + + + MB + + + + + {{ option[0] }} + + + +
+ Start VM in headless mode
+ + Use as a linked base VM (experimental) + +
+ + + Network + +
+ + + + + + + + + + + + + + + + {{ type }} + + + +
+
+ + Allow GNS3 to use any configured VirtualBox adapter + +
+ + + Usage + + + + + +
+
+ +
+
- - diff --git a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.spec.ts b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.spec.ts index 21c56211..86f07a5d 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.spec.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.spec.ts @@ -1,129 +1,139 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { Observable, of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of } from 'rxjs'; import { Server } from '../../../../models/server'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; -import { VirtualBoxTemplateDetailsComponent } from './virtual-box-template-details.component'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { VirtualBoxConfigurationService } from '../../../../services/virtual-box-configuration.service'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { VirtualBoxConfigurationService } from '../../../../services/virtual-box-configuration.service'; +import { VirtualBoxTemplateDetailsComponent } from './virtual-box-template-details.component'; export class MockedVirtualBoxService { - public getTemplate(server: Server, template_id: string) { - return of({} as VirtualBoxTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as VirtualBoxTemplate); + } - public saveTemplate(server: Server, virtualBoxTemplate: VirtualBoxTemplate) { - return of(virtualBoxTemplate); - } + public saveTemplate(server: Server, virtualBoxTemplate: VirtualBoxTemplate) { + return of(virtualBoxTemplate); + } } describe('VirtualBoxTemplateDetailsComponent', () => { - let component: VirtualBoxTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: VirtualBoxTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVirtualBoxService = new MockedVirtualBoxService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatTableModule , MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VirtualBoxService, useValue: mockedVirtualBoxService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: VirtualBoxConfigurationService, useClass: VirtualBoxConfigurationService } - ], - declarations: [ - VirtualBoxTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVirtualBoxService = new MockedVirtualBoxService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VirtualBoxTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VirtualBoxService, useValue: mockedVirtualBoxService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: VirtualBoxConfigurationService, useClass: VirtualBoxConfigurationService }, + ], + declarations: [VirtualBoxTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VirtualBoxTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedVirtualBoxService, 'saveTemplate').and.returnValue(of({} as VirtualBoxTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.generalSettingsForm.controls['ram'].setValue('256'); - component.networkForm.controls['adapters'].setValue('1'); - component.networkForm.controls['nameFormat'].setValue('{}'); - component.networkForm.controls['size'].setValue('256'); - component.virtualBoxTemplate = { - adapters: 0, - custom_adapters: [] - } as VirtualBoxTemplate; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedVirtualBoxService, 'saveTemplate').and.returnValue(of({} as VirtualBoxTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['ram'].setValue('256'); + component.networkForm.controls['adapters'].setValue('1'); + component.networkForm.controls['nameFormat'].setValue('{}'); + component.networkForm.controls['size'].setValue('256'); + component.virtualBoxTemplate = { + adapters: 0, + custom_adapters: [], + } as VirtualBoxTemplate; - expect(mockedVirtualBoxService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when general settings are not filled', () => { - spyOn(mockedVirtualBoxService, 'saveTemplate').and.returnValue(of({} as VirtualBoxTemplate)); - component.generalSettingsForm.controls['templateName'].setValue(''); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.generalSettingsForm.controls['ram'].setValue('256'); - component.networkForm.controls['adapters'].setValue('1'); - component.networkForm.controls['nameFormat'].setValue('{}'); - component.networkForm.controls['size'].setValue('256'); - component.virtualBoxTemplate = { - adapters: 0, - custom_adapters: [] - } as VirtualBoxTemplate; + expect(mockedVirtualBoxService.saveTemplate).toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when general settings are not filled', () => { + spyOn(mockedVirtualBoxService, 'saveTemplate').and.returnValue(of({} as VirtualBoxTemplate)); + component.generalSettingsForm.controls['templateName'].setValue(''); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['ram'].setValue('256'); + component.networkForm.controls['adapters'].setValue('1'); + component.networkForm.controls['nameFormat'].setValue('{}'); + component.networkForm.controls['size'].setValue('256'); + component.virtualBoxTemplate = { + adapters: 0, + custom_adapters: [], + } as VirtualBoxTemplate; - expect(mockedVirtualBoxService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when network settings are not filled', () => { - spyOn(mockedVirtualBoxService, 'saveTemplate').and.returnValue(of({} as VirtualBoxTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.generalSettingsForm.controls['ram'].setValue('256'); - component.networkForm.controls['adapters'].setValue(''); - component.networkForm.controls['nameFormat'].setValue('{}'); - component.networkForm.controls['size'].setValue('256'); - component.virtualBoxTemplate = { - adapters: 0, - custom_adapters: [] - } as VirtualBoxTemplate; + expect(mockedVirtualBoxService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when network settings are not filled', () => { + spyOn(mockedVirtualBoxService, 'saveTemplate').and.returnValue(of({} as VirtualBoxTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['ram'].setValue('256'); + component.networkForm.controls['adapters'].setValue(''); + component.networkForm.controls['nameFormat'].setValue('{}'); + component.networkForm.controls['size'].setValue('256'); + component.virtualBoxTemplate = { + adapters: 0, + custom_adapters: [], + } as VirtualBoxTemplate; - expect(mockedVirtualBoxService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedVirtualBoxService.saveTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts index 13fe3164..d66ac506 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts @@ -1,140 +1,143 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; -import { VirtualBoxService } from '../../../../services/virtual-box.service'; -import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; +import { Server } from '../../../../models/server'; +import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { VirtualBoxConfigurationService } from '../../../../services/virtual-box-configuration.service'; +import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { CustomAdaptersComponent } from '../../common/custom-adapters/custom-adapters.component'; - @Component({ - selector: 'app-virtual-box-template-details', - templateUrl: './virtual-box-template-details.component.html', - styleUrls: ['./virtual-box-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-virtual-box-template-details', + templateUrl: './virtual-box-template-details.component.html', + styleUrls: ['./virtual-box-template-details.component.scss', '../../preferences.component.scss'], }) export class VirtualBoxTemplateDetailsComponent implements OnInit { - server: Server; - virtualBoxTemplate: VirtualBoxTemplate; - isSymbolSelectionOpened: boolean = false; - consoleTypes: string[] = []; - onCloseOptions = []; - categories = []; - networkTypes = []; - displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type', 'actions']; - isConfiguratorOpened: boolean = false; - generalSettingsForm: FormGroup; - networkForm: FormGroup + server: Server; + virtualBoxTemplate: VirtualBoxTemplate; + isSymbolSelectionOpened: boolean = false; + consoleTypes: string[] = []; + onCloseOptions = []; + categories = []; + networkTypes = []; + displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type', 'actions']; + isConfiguratorOpened: boolean = false; + generalSettingsForm: FormGroup; + networkForm: FormGroup; - @ViewChild("customAdaptersConfigurator") - customAdaptersConfigurator: CustomAdaptersComponent; + @ViewChild('customAdaptersConfigurator') + customAdaptersConfigurator: CustomAdaptersComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private virtualBoxService: VirtualBoxService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private virtualBoxConfigurationService: VirtualBoxConfigurationService, - private router: Router - ) { - this.generalSettingsForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required), - ram: new FormControl('', Validators.required) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private virtualBoxService: VirtualBoxService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private virtualBoxConfigurationService: VirtualBoxConfigurationService, + private router: Router + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + ram: new FormControl('', Validators.required), + }); + + this.networkForm = this.formBuilder.group({ + adapters: new FormControl('', Validators.required), + nameFormat: new FormControl('', Validators.required), + size: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.virtualBoxService + .getTemplate(this.server, template_id) + .subscribe((virtualBoxTemplate: VirtualBoxTemplate) => { + this.virtualBoxTemplate = virtualBoxTemplate; + this.fillCustomAdapters(); }); + }); + } - this.networkForm = this.formBuilder.group({ - adapters: new FormControl('', Validators.required), - nameFormat: new FormControl('', Validators.required), - size: new FormControl('', Validators.required) + getConfiguration() { + this.consoleTypes = this.virtualBoxConfigurationService.getConsoleTypes(); + this.onCloseOptions = this.virtualBoxConfigurationService.getOnCloseoptions(); + this.categories = this.virtualBoxConfigurationService.getCategories(); + this.networkTypes = this.virtualBoxConfigurationService.getNetworkTypes(); + } + + setCustomAdaptersConfiguratorState(state: boolean) { + this.isConfiguratorOpened = state; + + if (state) { + this.fillCustomAdapters(); + this.customAdaptersConfigurator.numberOfAdapters = this.virtualBoxTemplate.adapters; + this.customAdaptersConfigurator.adapters = []; + this.virtualBoxTemplate.custom_adapters.forEach((adapter: CustomAdapter) => { + this.customAdaptersConfigurator.adapters.push({ + adapter_number: adapter.adapter_number, + adapter_type: adapter.adapter_type, + }); + }); + } + } + + saveCustomAdapters(adapters: CustomAdapter[]) { + this.setCustomAdaptersConfiguratorState(false); + this.virtualBoxTemplate.custom_adapters = adapters; + } + + fillCustomAdapters() { + let copyOfAdapters = this.virtualBoxTemplate.custom_adapters ? this.virtualBoxTemplate.custom_adapters : []; + this.virtualBoxTemplate.custom_adapters = []; + + for (let i = 0; i < this.virtualBoxTemplate.adapters; i++) { + if (copyOfAdapters[i]) { + this.virtualBoxTemplate.custom_adapters.push(copyOfAdapters[i]); + } else { + this.virtualBoxTemplate.custom_adapters.push({ + adapter_number: i, + adapter_type: 'e1000', + }); + } + } + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'virtualbox', 'templates']); + } + + onSave() { + if (this.generalSettingsForm.invalid || this.networkForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.fillCustomAdapters(); + + this.virtualBoxService + .saveTemplate(this.server, this.virtualBoxTemplate) + .subscribe((virtualBoxTemplate: VirtualBoxTemplate) => { + this.toasterService.success('Changes saved'); }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - this.getConfiguration(); - this.virtualBoxService.getTemplate(this.server, template_id).subscribe((virtualBoxTemplate: VirtualBoxTemplate) => { - this.virtualBoxTemplate = virtualBoxTemplate; - this.fillCustomAdapters(); - }); - }); - } - - getConfiguration(){ - this.consoleTypes = this.virtualBoxConfigurationService.getConsoleTypes(); - this.onCloseOptions = this.virtualBoxConfigurationService.getOnCloseoptions(); - this.categories = this.virtualBoxConfigurationService.getCategories(); - this.networkTypes = this.virtualBoxConfigurationService.getNetworkTypes(); - } - - setCustomAdaptersConfiguratorState(state: boolean) { - this.isConfiguratorOpened = state; - - if (state) { - this.fillCustomAdapters(); - this.customAdaptersConfigurator.numberOfAdapters = this.virtualBoxTemplate.adapters; - this.customAdaptersConfigurator.adapters = []; - this.virtualBoxTemplate.custom_adapters.forEach((adapter: CustomAdapter) => { - this.customAdaptersConfigurator.adapters.push({ - adapter_number: adapter.adapter_number, - adapter_type: adapter.adapter_type - }); - }); - } - } - - saveCustomAdapters(adapters: CustomAdapter[]){ - this.setCustomAdaptersConfiguratorState(false); - this.virtualBoxTemplate.custom_adapters = adapters; - } - - fillCustomAdapters() { - let copyOfAdapters = this.virtualBoxTemplate.custom_adapters ? this.virtualBoxTemplate.custom_adapters : []; - this.virtualBoxTemplate.custom_adapters = []; - - for(let i=0; i { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.virtualBoxTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.virtualBoxTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html index bb8f19b7..e7018d18 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html +++ b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html @@ -1,32 +1,46 @@
-
-
-

VirtualBox VM templates

- - -
+
+
+

VirtualBox VM templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.spec.ts b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.spec.ts index 6ae23965..dbdfc729 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.spec.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { Observable, of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of } from 'rxjs'; import { Server } from '../../../../models/server'; import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; -import { VirtualBoxTemplatesComponent } from './virtual-box-templates.component'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VirtualBoxTemplatesComponent } from './virtual-box-templates.component'; export class MockedVirtualBoxService { - public getTemplates(server: Server) { - return of([{} as VirtualBoxTemplate]); - } + public getTemplates(server: Server) { + return of([{} as VirtualBoxTemplate]); + } } describe('VirtualBoxTemplatesComponent', () => { - let component: VirtualBoxTemplatesComponent; - let fixture: ComponentFixture; + let component: VirtualBoxTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVirtualBoxService = new MockedVirtualBoxService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VirtualBoxService, useValue: mockedVirtualBoxService } - ], - declarations: [ - VirtualBoxTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVirtualBoxService = new MockedVirtualBoxService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VirtualBoxTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VirtualBoxService, useValue: mockedVirtualBoxService }, + ], + declarations: [VirtualBoxTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VirtualBoxTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts index 357f254c..93ddbee7 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts @@ -1,48 +1,49 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; +import { Server } from '../../../../models/server'; import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; +import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; +import { ServerService } from '../../../../services/server.service'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; -import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; - @Component({ - selector: 'app-virtual-box-templates', - templateUrl: './virtual-box-templates.component.html', - styleUrls: ['./virtual-box-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-virtual-box-templates', + templateUrl: './virtual-box-templates.component.html', + styleUrls: ['./virtual-box-templates.component.scss', '../../preferences.component.scss'], }) export class VirtualBoxTemplatesComponent implements OnInit { - server: Server; - virtualBoxTemplates: VirtualBoxTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + virtualBoxTemplates: VirtualBoxTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private virtualBoxService: VirtualBoxService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private virtualBoxService: VirtualBoxService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates(){ - this.virtualBoxService.getTemplates(this.server).subscribe((virtualBoxTemplates: VirtualBoxTemplate[]) => { - this.virtualBoxTemplates = virtualBoxTemplates.filter((elem) => elem.template_type === 'virtualbox' && !elem.builtin); - }); - } + getTemplates() { + this.virtualBoxService.getTemplates(this.server).subscribe((virtualBoxTemplates: VirtualBoxTemplate[]) => { + this.virtualBoxTemplates = virtualBoxTemplates.filter( + (elem) => elem.template_type === 'virtualbox' && !elem.builtin + ); + }); + } - deleteTemplate(template: VpcsTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: VpcsTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html index 6fea2574..40261c2d 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html @@ -1,30 +1,27 @@
-
-
-

New VMware VM template

-
+
+
+

New VMware VM template

-
- -
- - - - {{vm.vmname}} - - -
- - Use as a linked base VM (experimental) - -
-
-
- - -
+
+
+ +
+ + + + {{ vm.vmname }} + +
+ + Use as a linked base VM (experimental) + +
+
+
+ +
+
diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts index dd2ccabe..3fa8c694 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts @@ -1,72 +1,71 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { ToasterService } from '../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; import { v4 as uuid } from 'uuid'; -import { VmwareVm } from '../../../../models/vmware/vmware-vm'; +import { Server } from '../../../../models/server'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; +import { VmwareVm } from '../../../../models/vmware/vmware-vm'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { VmwareService } from '../../../../services/vmware.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; - @Component({ - selector: 'app-add-vmware-template', - templateUrl: './add-vmware-template.component.html', - styleUrls: ['./add-vmware-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-vmware-template', + templateUrl: './add-vmware-template.component.html', + styleUrls: ['./add-vmware-template.component.scss', '../../preferences.component.scss'], }) export class AddVmwareTemplateComponent implements OnInit { - server: Server; - virtualMachines: VmwareVm[]; - selectedVM: VmwareVm; - vmwareTemplate: VmwareTemplate; - templateNameForm: FormGroup; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private vmwareService: VmwareService, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private router: Router, - private formBuilder: FormBuilder - ) { - this.templateNameForm = this.formBuilder.group({ - templateName: new FormControl(null, [Validators.required]) + server: Server; + virtualMachines: VmwareVm[]; + selectedVM: VmwareVm; + vmwareTemplate: VmwareTemplate; + templateNameForm: FormGroup; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private vmwareService: VmwareService, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private router: Router, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl(null, [Validators.required]), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.vmwareService.getVirtualMachines(this.server).subscribe((virtualMachines: VmwareVm[]) => { + this.virtualMachines = virtualMachines; + + this.templateMocksService.getVmwareTemplate().subscribe((template: VmwareTemplate) => { + this.vmwareTemplate = template; }); + }); + }); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); + } + + addTemplate() { + if (!this.templateNameForm.invalid) { + this.vmwareTemplate.name = this.selectedVM.vmname; + this.vmwareTemplate.vmx_path = this.selectedVM.vmx_path; + this.vmwareTemplate.template_id = uuid(); + + this.vmwareService.addTemplate(this.server, this.vmwareTemplate).subscribe(() => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } - - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - - this.vmwareService.getVirtualMachines(this.server).subscribe((virtualMachines: VmwareVm[]) => { - this.virtualMachines = virtualMachines; - - this.templateMocksService.getVmwareTemplate().subscribe((template: VmwareTemplate) => { - this.vmwareTemplate = template; - }); - }) - }); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); - } - - addTemplate() { - if (!this.templateNameForm.invalid) { - this.vmwareTemplate.name = this.selectedVM.vmname; - this.vmwareTemplate.vmx_path = this.selectedVM.vmx_path; - this.vmwareTemplate.template_id = uuid(); - - this.vmwareService.addTemplate(this.server, this.vmwareTemplate).subscribe(() => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } - } + } } diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts b/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts index 5a3b65c2..b707db8c 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts @@ -1,106 +1,106 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; -import { AddVmwareTemplateComponent } from './add-vmware-template.component'; -import { VmwareService } from '../../../../services/vmware.service'; import { VmwareVm } from '../../../../models/vmware/vmware-vm'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { VmwareService } from '../../../../services/vmware.service'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { AddVmwareTemplateComponent } from './add-vmware-template.component'; export class MockedVmwareService { - public addTemplate(server: Server, vmwareTemplate: VmwareTemplate) { - return of(vmwareTemplate); - } + public addTemplate(server: Server, vmwareTemplate: VmwareTemplate) { + return of(vmwareTemplate); + } - public getVirtualMachines(server: Server) { - return of([]); - } + public getVirtualMachines(server: Server) { + return of([]); + } } describe('AddVmwareTemplateComponent', () => { - let component: AddVmwareTemplateComponent; - let fixture: ComponentFixture; + let component: AddVmwareTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVmwareService = new MockedVmwareService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/vmware/templates', component: AddVmwareTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VmwareService, useValue: mockedVmwareService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: TemplateMocksService, useClass: TemplateMocksService } - ], - declarations: [ - AddVmwareTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVmwareService = new MockedVmwareService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(AddVmwareTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/vmware/templates', component: AddVmwareTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VmwareService, useValue: mockedVmwareService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + ], + declarations: [AddVmwareTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AddVmwareTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedVmwareService, 'addTemplate').and.returnValue(of({} as VmwareTemplate)); - let template: VmwareVm = { - vmname: 'test', - vmx_path: '' - }; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.vmwareTemplate = {} as VmwareTemplate; - component.selectedVM = template; - component.server = {id: 1} as Server; - component.templateNameForm.controls['templateName'].setValue('template name'); + it('should call save template', () => { + spyOn(mockedVmwareService, 'addTemplate').and.returnValue(of({} as VmwareTemplate)); + let template: VmwareVm = { + vmname: 'test', + vmx_path: '', + }; - component.addTemplate(); + component.vmwareTemplate = {} as VmwareTemplate; + component.selectedVM = template; + component.server = { id: 1 } as Server; + component.templateNameForm.controls['templateName'].setValue('template name'); - expect(mockedVmwareService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call save template when virtual machine is not selected', () => { - spyOn(mockedVmwareService, 'addTemplate').and.returnValue(of({} as VmwareTemplate)); - component.server = {id: 1} as Server; + expect(mockedVmwareService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call save template when virtual machine is not selected', () => { + spyOn(mockedVmwareService, 'addTemplate').and.returnValue(of({} as VmwareTemplate)); + component.server = { id: 1 } as Server; - expect(mockedVmwareService.addTemplate).not.toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedVmwareService.addTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.html b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.html index 2f7bc390..1effcbab 100644 --- a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.html +++ b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.html @@ -1,12 +1,12 @@
-
-
-

VMware preferences

-
-
-
- - - +
+
+

VMware preferences

+
+
+ + + +
diff --git a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.scss b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.scss index 9c2173c2..8aff6f5a 100644 --- a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.scss +++ b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.scss @@ -1,3 +1,3 @@ .form-field { - width: 100%; + width: 100%; } diff --git a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.spec.ts b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.spec.ts index 60cb6ab1..59c6e54e 100644 --- a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.spec.ts +++ b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.spec.ts @@ -1,55 +1,61 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; +import { RouterTestingModule } from '@angular/router/testing'; import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; import { VmwarePreferencesComponent } from './vmware-preferences.component'; describe('VmwarePreferencesComponent', () => { - let component: VmwarePreferencesComponent; - let fixture: ComponentFixture; + let component: VmwarePreferencesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService } - ], - declarations: [ - VmwarePreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VmwarePreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + ], + declarations: [VmwarePreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VmwarePreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should clear path to executable', () => { - component.restoreDefaults(); + it('should create', () => { + expect(component).toBeTruthy(); + }); - expect(component.vmrunPath).toBe(''); - }); + it('should clear path to executable', () => { + component.restoreDefaults(); + + expect(component.vmrunPath).toBe(''); + }); }); diff --git a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.ts b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.ts index c8da405f..d8b16b60 100644 --- a/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.ts +++ b/src/app/components/preferences/vmware/vmware-preferences/vmware-preferences.component.ts @@ -1,33 +1,28 @@ -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; -import { switchMap } from 'rxjs/operators'; import { ServerService } from '../../../../services/server.service'; - @Component({ - selector: 'app-vmware-preferences', - templateUrl: './vmware-preferences.component.html', - styleUrls: ['./vmware-preferences.component.scss'] + selector: 'app-vmware-preferences', + templateUrl: './vmware-preferences.component.html', + styleUrls: ['./vmware-preferences.component.scss'], }) export class VmwarePreferencesComponent implements OnInit { - server: Server; - vmrunPath: string; + server: Server; + vmrunPath: string; - constructor( - private route: ActivatedRoute, - private serverService: ServerService - ) {} + constructor(private route: ActivatedRoute, private serverService: ServerService) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - }); - } + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + }); + } - restoreDefaults(){ - this.vmrunPath = ''; - } + restoreDefaults() { + this.vmrunPath = ''; + } } diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html index 44a6de61..a7b1b2d3 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html @@ -1,145 +1,144 @@
-
-
-

VMware VM configuration

-
+
+
+

VMware VM configuration

-
- - - - - General settings - - -
- - - - - - - - - -

- - - - {{category[0]}} - - - - - - - {{type}} - - - - - Auto start console - - - - - {{option[0]}} - - - - - Start VM in headless mode -

- - Use as a linked base VM (experimental) - -
-
- - - - Network - - - - - - - - - - - - - - - - - - {{type}} - - - -
- - Allow GNS3 to override non custom VMware adapter - -
- - - - Usage - - - - - - -
-
- - -
+
+
+ + + + General settings + +
+ + + + + + + + + +

+ + + + {{ category[0] }} + + + + + + + {{ type }} + + + + + Auto start console + + + + + {{ option[0] }} + + + + + Start VM in headless mode

+ + Use as a linked base VM (experimental) + +
+
+ + + Network + + + + + + + + + + + + + + + + + {{ type }} + + + +
+ + Allow GNS3 to override non custom VMware adapter + +
+ + + Usage + + + + + +
+
+ +
+
- - diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts index 40d23067..1d618a03 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts @@ -1,132 +1,142 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { Observable, of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of } from 'rxjs'; import { Server } from '../../../../models/server'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; -import { VmwareTemplateDetailsComponent } from './vmware-template-details.component'; -import { VmwareService } from '../../../../services/vmware.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { VmwareConfigurationService } from '../../../../services/vmware-configuration.service'; +import { VmwareService } from '../../../../services/vmware.service'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VmwareTemplateDetailsComponent } from './vmware-template-details.component'; export class MockedVmwareService { - public getTemplate(server: Server, template_id: string) { - return of({} as VmwareTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as VmwareTemplate); + } - public saveTemplate(server: Server, vmwareTemplate: VmwareTemplate) { - return of(vmwareTemplate); - } + public saveTemplate(server: Server, vmwareTemplate: VmwareTemplate) { + return of(vmwareTemplate); + } } describe('VmwareTemplateDetailsComponent', () => { - let component: VmwareTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: VmwareTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVmwareService = new MockedVmwareService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatTableModule , MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VmwareService, useValue: mockedVmwareService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: VmwareConfigurationService, useClass: VmwareConfigurationService } - ], - declarations: [ - VmwareTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVmwareService = new MockedVmwareService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VmwareTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatTableModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VmwareService, useValue: mockedVmwareService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: VmwareConfigurationService, useClass: VmwareConfigurationService }, + ], + declarations: [VmwareTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VmwareTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.vmwareTemplate = { - adapters: 0, - custom_adapters: [] - } as VmwareTemplate; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.vmwareTemplate = { + adapters: 0, + custom_adapters: [], + } as VmwareTemplate; - expect(mockedVmwareService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when template name is empty', () => { - spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.generalSettingsForm.controls['templateName'].setValue(''); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.vmwareTemplate = { - adapters: 0, - custom_adapters: [] - } as VmwareTemplate; + expect(mockedVmwareService.saveTemplate).toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when template name is empty', () => { + spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); + component.generalSettingsForm.controls['templateName'].setValue(''); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.vmwareTemplate = { + adapters: 0, + custom_adapters: [], + } as VmwareTemplate; - expect(mockedVmwareService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when default name is empty', () => { - spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue(''); - component.generalSettingsForm.controls['symbol'].setValue('symbol'); - component.vmwareTemplate = { - adapters: 0, - custom_adapters: [] - } as VmwareTemplate; + expect(mockedVmwareService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when default name is empty', () => { + spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue(''); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); + component.vmwareTemplate = { + adapters: 0, + custom_adapters: [], + } as VmwareTemplate; - expect(mockedVmwareService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when symbol path is empty', () => { - spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.generalSettingsForm.controls['templateName'].setValue('template name'); - component.generalSettingsForm.controls['defaultName'].setValue('default name'); - component.generalSettingsForm.controls['symbol'].setValue(''); - component.vmwareTemplate = { - adapters: 0, - custom_adapters: [] - } as VmwareTemplate; + expect(mockedVmwareService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when symbol path is empty', () => { + spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue(''); + component.vmwareTemplate = { + adapters: 0, + custom_adapters: [], + } as VmwareTemplate; - expect(mockedVmwareService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedVmwareService.saveTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts index ff451779..a282afcd 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts @@ -1,131 +1,130 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; -import { VmwareTemplate } from '../../../../models/templates/vmware-template'; -import { VmwareService } from '../../../../services/vmware.service'; -import { VmwareConfigurationService } from '../../../../services/vmware-configuration.service'; import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; +import { Server } from '../../../../models/server'; +import { VmwareTemplate } from '../../../../models/templates/vmware-template'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { VmwareConfigurationService } from '../../../../services/vmware-configuration.service'; +import { VmwareService } from '../../../../services/vmware.service'; import { CustomAdaptersComponent } from '../../common/custom-adapters/custom-adapters.component'; - @Component({ - selector: 'app-vmware-template-details', - templateUrl: './vmware-template-details.component.html', - styleUrls: ['./vmware-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-vmware-template-details', + templateUrl: './vmware-template-details.component.html', + styleUrls: ['./vmware-template-details.component.scss', '../../preferences.component.scss'], }) export class VmwareTemplateDetailsComponent implements OnInit { - server: Server; - vmwareTemplate: VmwareTemplate; - generalSettingsForm: FormGroup; - displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type', 'actions']; - isConfiguratorOpened: boolean = false; - isSymbolSelectionOpened: boolean = false; - consoleTypes: string[] = []; - categories = []; - onCloseOptions = []; - networkTypes = []; + server: Server; + vmwareTemplate: VmwareTemplate; + generalSettingsForm: FormGroup; + displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type', 'actions']; + isConfiguratorOpened: boolean = false; + isSymbolSelectionOpened: boolean = false; + consoleTypes: string[] = []; + categories = []; + onCloseOptions = []; + networkTypes = []; - @ViewChild("customAdaptersConfigurator") - customAdaptersConfigurator: CustomAdaptersComponent; + @ViewChild('customAdaptersConfigurator') + customAdaptersConfigurator: CustomAdaptersComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private vmwareService: VmwareService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private vmwareConfigurationService: VmwareConfigurationService, - private router: Router - ) { - this.generalSettingsForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private vmwareService: VmwareService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private vmwareConfigurationService: VmwareConfigurationService, + private router: Router + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.vmwareService.getTemplate(this.server, template_id).subscribe((vmwareTemplate: VmwareTemplate) => { + this.vmwareTemplate = vmwareTemplate; + this.fillCustomAdapters(); + }); + }); + } + + getConfiguration() { + this.consoleTypes = this.vmwareConfigurationService.getConsoleTypes(); + this.categories = this.vmwareConfigurationService.getCategories(); + this.onCloseOptions = this.vmwareConfigurationService.getOnCloseoptions(); + this.networkTypes = this.vmwareConfigurationService.getNetworkTypes(); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); + } + + onSave() { + if (this.generalSettingsForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.fillCustomAdapters(); + + this.vmwareService.saveTemplate(this.server, this.vmwareTemplate).subscribe((vmwareTemplate: VmwareTemplate) => { + this.toasterService.success('Changes saved'); + }); + } + } + + setCustomAdaptersConfiguratorState(state: boolean) { + this.isConfiguratorOpened = state; + + if (state) { + this.fillCustomAdapters(); + this.customAdaptersConfigurator.numberOfAdapters = this.vmwareTemplate.adapters; + this.customAdaptersConfigurator.adapters = []; + this.vmwareTemplate.custom_adapters.forEach((adapter: CustomAdapter) => { + this.customAdaptersConfigurator.adapters.push({ + adapter_number: adapter.adapter_number, + adapter_type: adapter.adapter_type, }); + }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + saveCustomAdapters(adapters: CustomAdapter[]) { + this.setCustomAdaptersConfiguratorState(false); + this.vmwareTemplate.custom_adapters = adapters; + } - this.getConfiguration(); - this.vmwareService.getTemplate(this.server, template_id).subscribe((vmwareTemplate: VmwareTemplate) => { - this.vmwareTemplate = vmwareTemplate; - this.fillCustomAdapters(); - }); + fillCustomAdapters() { + let copyOfAdapters = this.vmwareTemplate.custom_adapters ? this.vmwareTemplate.custom_adapters : []; + this.vmwareTemplate.custom_adapters = []; + + for (let i = 0; i < this.vmwareTemplate.adapters; i++) { + if (copyOfAdapters[i]) { + this.vmwareTemplate.custom_adapters.push(copyOfAdapters[i]); + } else { + this.vmwareTemplate.custom_adapters.push({ + adapter_number: i, + adapter_type: 'e1000', }); + } } + } - getConfiguration() { - this.consoleTypes = this.vmwareConfigurationService.getConsoleTypes(); - this.categories = this.vmwareConfigurationService.getCategories(); - this.onCloseOptions = this.vmwareConfigurationService.getOnCloseoptions(); - this.networkTypes = this.vmwareConfigurationService.getNetworkTypes(); - } + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); - } - - onSave() { - if (this.generalSettingsForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.fillCustomAdapters(); - - this.vmwareService.saveTemplate(this.server, this.vmwareTemplate).subscribe((vmwareTemplate: VmwareTemplate) => { - this.toasterService.success("Changes saved"); - }); - } - } - - setCustomAdaptersConfiguratorState(state: boolean) { - this.isConfiguratorOpened = state; - - if (state) { - this.fillCustomAdapters(); - this.customAdaptersConfigurator.numberOfAdapters = this.vmwareTemplate.adapters; - this.customAdaptersConfigurator.adapters = []; - this.vmwareTemplate.custom_adapters.forEach((adapter: CustomAdapter) => { - this.customAdaptersConfigurator.adapters.push({ - adapter_number: adapter.adapter_number, - adapter_type: adapter.adapter_type - }); - }); - } - } - - saveCustomAdapters(adapters: CustomAdapter[]){ - this.setCustomAdaptersConfiguratorState(false); - this.vmwareTemplate.custom_adapters = adapters; - } - - fillCustomAdapters() { - let copyOfAdapters = this.vmwareTemplate.custom_adapters ? this.vmwareTemplate.custom_adapters : []; - this.vmwareTemplate.custom_adapters = []; - - for(let i=0; i -
-
-

VMware VM templates

- - -
+
+
+

VMware VM templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.spec.ts b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.spec.ts index 4ff8efcc..95221b5f 100644 --- a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.spec.ts +++ b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { Observable, of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of } from 'rxjs'; import { Server } from '../../../../models/server'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; -import { VmwareTemplatesComponent } from './vmware-templates.component'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { VmwareService } from '../../../../services/vmware.service'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VmwareTemplatesComponent } from './vmware-templates.component'; export class MockedVmwareService { - public getTemplates(server: Server) { - return of([{} as VmwareTemplate]); - } + public getTemplates(server: Server) { + return of([{} as VmwareTemplate]); + } } describe('VmwareTemplatesComponent', () => { - let component: VmwareTemplatesComponent; - let fixture: ComponentFixture; + let component: VmwareTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVmwareService = new MockedVmwareService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VmwareService, useValue: mockedVmwareService } - ], - declarations: [ - VmwareTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVmwareService = new MockedVmwareService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VmwareTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VmwareService, useValue: mockedVmwareService }, + ], + declarations: [VmwareTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VmwareTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts index 5f1a941e..8700c3b6 100644 --- a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts +++ b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts @@ -1,47 +1,46 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; +import { Server } from '../../../../models/server'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; +import { ServerService } from '../../../../services/server.service'; import { VmwareService } from '../../../../services/vmware.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; - @Component({ - selector: 'app-vmware-templates', - templateUrl: './vmware-templates.component.html', - styleUrls: ['./vmware-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-vmware-templates', + templateUrl: './vmware-templates.component.html', + styleUrls: ['./vmware-templates.component.scss', '../../preferences.component.scss'], }) export class VmwareTemplatesComponent implements OnInit { - server: Server; - vmwareTemplates: VmwareTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + vmwareTemplates: VmwareTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private vmwareService: VmwareService - ) {} + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private vmwareService: VmwareService + ) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.vmwareService.getTemplates(this.server).subscribe((vmwareTemplates: VmwareTemplate[]) => { - this.vmwareTemplates = vmwareTemplates.filter((elem) => elem.template_type === 'vmware' && !elem.builtin); - }); - } + getTemplates() { + this.vmwareService.getTemplates(this.server).subscribe((vmwareTemplates: VmwareTemplate[]) => { + this.vmwareTemplates = vmwareTemplates.filter((elem) => elem.template_type === 'vmware' && !elem.builtin); + }); + } - deleteTemplate(template: VmwareTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: VmwareTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html index 17a5f6d1..f650eb76 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html @@ -1,25 +1,33 @@
-
-
-

New VPCS node template

-
+
+
+

New VPCS node template

-
- - - Run the VPCS node locally - Run the VPCS node on the GNS3 VM - +
+
+ + + Run the VPCS node locally + Run the VPCS node on the GNS3 VM + -
- - - -
-
-
- - -
+
+ + + +
+ +
+ +
+
diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts index 86e3bcfc..fb84fad5 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts @@ -1,107 +1,107 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; -import { AddVpcsTemplateComponent } from './add-vpcs-template.component'; import { Server } from '../../../../models/server'; -import { VpcsService } from '../../../../services/vpcs.service'; -import { ToasterService } from '../../../../services/toaster.service'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ComputeService } from '../../../../services/compute.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; +import { VpcsService } from '../../../../services/vpcs.service'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { AddVpcsTemplateComponent } from './add-vpcs-template.component'; export class MockedComputeService { - getComputes(server: Server) { - return of([]); - } + getComputes(server: Server) { + return of([]); + } } export class MockedVpcsService { - public addTemplate(server: Server, vpcsTemplate: VpcsTemplate) { - return of(vpcsTemplate); - } + public addTemplate(server: Server, vpcsTemplate: VpcsTemplate) { + return of(vpcsTemplate); + } } describe('AddVpcsTemplateComponent', () => { - let component: AddVpcsTemplateComponent; - let fixture: ComponentFixture; + let component: AddVpcsTemplateComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVpcsService = new MockedVpcsService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - let mockedComputeService = new MockedComputeService(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - FormsModule, - ReactiveFormsModule, - MatIconModule, - MatToolbarModule, - MatMenuModule, - MatCheckboxModule, - CommonModule, - NoopAnimationsModule, - RouterTestingModule.withRoutes([{path: 'server/1/preferences/vpcs/templates', component: AddVpcsTemplateComponent}]) - ], - providers: [ - { provide: ActivatedRoute, useValue: activatedRoute }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VpcsService, useValue: mockedVpcsService }, - { provide: ToasterService, useValue: mockedToasterService }, - { provide: ComputeService, useValue: mockedComputeService }, - { provide: TemplateMocksService, useClass: TemplateMocksService } - ], - declarations: [ - AddVpcsTemplateComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVpcsService = new MockedVpcsService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); + let mockedComputeService = new MockedComputeService(); - beforeEach(() => { - fixture = TestBed.createComponent(AddVpcsTemplateComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([ + { path: 'server/1/preferences/vpcs/templates', component: AddVpcsTemplateComponent }, + ]), + ], + providers: [ + { provide: ActivatedRoute, useValue: activatedRoute }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VpcsService, useValue: mockedVpcsService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: ComputeService, useValue: mockedComputeService }, + { provide: TemplateMocksService, useClass: TemplateMocksService }, + ], + declarations: [AddVpcsTemplateComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AddVpcsTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call add template', () => { - spyOn(mockedVpcsService, 'addTemplate').and.returnValue(of({} as VpcsTemplate)); - component.templateName = "sample name"; - component.templateNameForm.controls['templateName'].setValue('template name'); - component.server = {id: 1} as Server; + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.addTemplate(); + it('should call add template', () => { + spyOn(mockedVpcsService, 'addTemplate').and.returnValue(of({} as VpcsTemplate)); + component.templateName = 'sample name'; + component.templateNameForm.controls['templateName'].setValue('template name'); + component.server = { id: 1 } as Server; - expect(mockedVpcsService.addTemplate).toHaveBeenCalled(); - }); + component.addTemplate(); - it('should not call add template when template name is empty', () => { - spyOn(mockedVpcsService, 'addTemplate').and.returnValue(of({} as VpcsTemplate)); - spyOn(mockedToasterService, 'error'); - component.templateName = ""; - component.server = {id: 1} as Server; + expect(mockedVpcsService.addTemplate).toHaveBeenCalled(); + }); - component.addTemplate(); + it('should not call add template when template name is empty', () => { + spyOn(mockedVpcsService, 'addTemplate').and.returnValue(of({} as VpcsTemplate)); + spyOn(mockedToasterService, 'error'); + component.templateName = ''; + component.server = { id: 1 } as Server; - expect(mockedVpcsService.addTemplate).not.toHaveBeenCalled(); - expect(mockedToasterService.error).toHaveBeenCalled(); - }); + component.addTemplate(); + + expect(mockedVpcsService.addTemplate).not.toHaveBeenCalled(); + expect(mockedToasterService.error).toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts index 3253ad95..72feec80 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts @@ -1,90 +1,89 @@ -import { Component, OnInit } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; -import { VpcsService } from '../../../../services/vpcs.service'; -import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; -import { ToasterService } from '../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; -import { TemplateMocksService } from '../../../../services/template-mocks.service'; -import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; -import { ComputeService } from '../../../../services/compute.service'; import { Compute } from '../../../../models/compute'; - +import { Server } from '../../../../models/server'; +import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; +import { ComputeService } from '../../../../services/compute.service'; +import { ServerService } from '../../../../services/server.service'; +import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { ToasterService } from '../../../../services/toaster.service'; +import { VpcsService } from '../../../../services/vpcs.service'; @Component({ - selector: 'app-add-vpcs-template', - templateUrl: './add-vpcs-template.component.html', - styleUrls: ['./add-vpcs-template.component.scss', '../../preferences.component.scss'] + selector: 'app-add-vpcs-template', + templateUrl: './add-vpcs-template.component.html', + styleUrls: ['./add-vpcs-template.component.scss', '../../preferences.component.scss'], }) export class AddVpcsTemplateComponent implements OnInit { - server: Server; - templateName: string = ''; - templateNameForm: FormGroup + server: Server; + templateName: string = ''; + templateNameForm: FormGroup; - isGns3VmAvailable: boolean = false; - isGns3VmChosen: boolean = false; - isLocalComputerChosen: boolean = true; - - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private vpcsService: VpcsService, - private router: Router, - private toasterService: ToasterService, - private templateMocksService: TemplateMocksService, - private formBuilder: FormBuilder, - private computeService: ComputeService - ) { - this.templateNameForm = this.formBuilder.group({ - templateName: new FormControl(null, [Validators.required]) - }); + isGns3VmAvailable: boolean = false; + isGns3VmChosen: boolean = false; + isLocalComputerChosen: boolean = true; + + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private vpcsService: VpcsService, + private router: Router, + private toasterService: ToasterService, + private templateMocksService: TemplateMocksService, + private formBuilder: FormBuilder, + private computeService: ComputeService + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl(null, [Validators.required]), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.computeService.getComputes(server).subscribe((computes: Compute[]) => { + if (computes.filter((compute) => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; + }); + }); + } + + setServerType(serverType: string) { + if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { + this.isGns3VmChosen = true; + this.isLocalComputerChosen = false; + } else { + this.isGns3VmChosen = false; + this.isLocalComputerChosen = true; } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); + } - this.computeService.getComputes(server).subscribe((computes: Compute[]) => { - if (computes.filter(compute => compute.compute_id === 'vm').length > 0) this.isGns3VmAvailable = true; - }); - }); - } - - setServerType(serverType: string) { - if (serverType === 'gns3 vm' && this.isGns3VmAvailable) { - this.isGns3VmChosen = true; - this.isLocalComputerChosen = false; - } else { - this.isGns3VmChosen = false; - this.isLocalComputerChosen = true; - } - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); - } - - addTemplate() { - if (!this.templateNameForm.invalid) { - this.templateName = this.templateNameForm.get('templateName').value; - - let vpcsTemplate: VpcsTemplate; - - this.templateMocksService.getVpcsTemplate().subscribe((template: VpcsTemplate) => { - vpcsTemplate = template; - }); - - vpcsTemplate.template_id = uuid(), - vpcsTemplate.name = this.templateName, - vpcsTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'; - - this.vpcsService.addTemplate(this.server, vpcsTemplate).subscribe(() => { - this.goBack(); - }); - } else { - this.toasterService.error(`Fill all required fields`); - } + addTemplate() { + if (!this.templateNameForm.invalid) { + this.templateName = this.templateNameForm.get('templateName').value; + + let vpcsTemplate: VpcsTemplate; + + this.templateMocksService.getVpcsTemplate().subscribe((template: VpcsTemplate) => { + vpcsTemplate = template; + }); + + (vpcsTemplate.template_id = uuid()), + (vpcsTemplate.name = this.templateName), + (vpcsTemplate.compute_id = this.isGns3VmChosen ? 'vm' : 'local'); + + this.vpcsService.addTemplate(this.server, vpcsTemplate).subscribe(() => { + this.goBack(); + }); + } else { + this.toasterService.error(`Fill all required fields`); } + } } diff --git a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.html b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.html index 33c19621..58b89cb9 100644 --- a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.html +++ b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.html @@ -1,12 +1,12 @@
-
-
-

VPCS preferences

-
-
-
- - - +
+
+

VPCS preferences

+
+
+ + + +
diff --git a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.scss b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.scss index 9c2173c2..8aff6f5a 100644 --- a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.scss +++ b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.scss @@ -1,3 +1,3 @@ .form-field { - width: 100%; + width: 100%; } diff --git a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.spec.ts b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.spec.ts index a9658f98..c6ff9dbe 100644 --- a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.spec.ts +++ b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.spec.ts @@ -1,55 +1,61 @@ -import { VpcsPreferencesComponent } from "./vpcs-preferences.component"; -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; +import { RouterTestingModule } from '@angular/router/testing'; import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VpcsPreferencesComponent } from './vpcs-preferences.component'; describe('VpcsPreferencesComponent', () => { - let component: VpcsPreferencesComponent; - let fixture: ComponentFixture; + let component: VpcsPreferencesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService } - ], - declarations: [ - VpcsPreferencesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VpcsPreferencesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + ], + declarations: [VpcsPreferencesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VpcsPreferencesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should clear path to executable', () => { - component.restoreDefaults(); + it('should create', () => { + expect(component).toBeTruthy(); + }); - expect(component.vpcsExecutable).toBe(''); - }); + it('should clear path to executable', () => { + component.restoreDefaults(); + + expect(component.vpcsExecutable).toBe(''); + }); }); diff --git a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts index 641746b1..9d5fa383 100644 --- a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts +++ b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts @@ -1,32 +1,28 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; import { ServerService } from '../../../../services/server.service'; - @Component({ - selector: 'app-vpcs-preferences', - templateUrl: './vpcs-preferences.component.html', - styleUrls: ['./vpcs-preferences.component.scss'] + selector: 'app-vpcs-preferences', + templateUrl: './vpcs-preferences.component.html', + styleUrls: ['./vpcs-preferences.component.scss'], }) export class VpcsPreferencesComponent implements OnInit { - server: Server; - vpcsExecutable: string; + server: Server; + vpcsExecutable: string; - constructor( - private route: ActivatedRoute, - private serverService: ServerService - ) {} + constructor(private route: ActivatedRoute, private serverService: ServerService) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - }); - } + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + }); + } - restoreDefaults(){ - this.vpcsExecutable = ''; - } + restoreDefaults() { + this.vpcsExecutable = ''; + } } diff --git a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html index fa2601a3..922e88c2 100644 --- a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html +++ b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html @@ -1,72 +1,79 @@
-
-
-

VPCS device configuration

-
+
+
+

VPCS device configuration

-
- -
- - - - - - - - - - - - -

- - - - {{category[0]}} - - - - - - - {{type}} - - - - - Auto start console - -
-
-
- - -
+
+
+ +
+ + + + + + + + + + + + +

+ + + + {{ category[0] }} + + + + + + + {{ type }} + + + + + Auto start console + +
+
+
+ +
+
- + diff --git a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.spec.ts b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.spec.ts index 18d9963c..608635d3 100644 --- a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.spec.ts +++ b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.spec.ts @@ -1,131 +1,140 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; -import { VpcsTemplateDetailsComponent } from './vpcs-template-details.component'; import { Server } from '../../../../models/server'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; -import { MockedToasterService } from '../../../../services/toaster.service.spec'; -import { VpcsService } from '../../../../services/vpcs.service'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; import { ToasterService } from '../../../../services/toaster.service'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { VpcsConfigurationService } from '../../../../services/vpcs-configuration.service'; +import { VpcsService } from '../../../../services/vpcs.service'; +import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VpcsTemplateDetailsComponent } from './vpcs-template-details.component'; export class MockedVpcsService { - public getTemplate(server: Server, template_id: string) { - return of({} as VpcsTemplate); - } + public getTemplate(server: Server, template_id: string) { + return of({} as VpcsTemplate); + } - public saveTemplate(server: Server, vpcsTemplate: VpcsTemplate) { - return of(vpcsTemplate); - } + public saveTemplate(server: Server, vpcsTemplate: VpcsTemplate) { + return of(vpcsTemplate); + } } describe('VpcsTemplateDetailsComponent', () => { - let component: VpcsTemplateDetailsComponent; - let fixture: ComponentFixture; + let component: VpcsTemplateDetailsComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVpcsService = new MockedVpcsService; - let mockedToasterService = new MockedToasterService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VpcsService, useValue: mockedVpcsService }, - { provide: ToasterService, useValue: mockedToasterService}, - { provide: VpcsConfigurationService, useClass: VpcsConfigurationService } - ], - declarations: [ - VpcsTemplateDetailsComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVpcsService = new MockedVpcsService(); + let mockedToasterService = new MockedToasterService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VpcsTemplateDetailsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + FormsModule, + ReactiveFormsModule, + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VpcsService, useValue: mockedVpcsService }, + { provide: ToasterService, useValue: mockedToasterService }, + { provide: VpcsConfigurationService, useClass: VpcsConfigurationService }, + ], + declarations: [VpcsTemplateDetailsComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VpcsTemplateDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should call save template', () => { - spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['scriptFile'].setValue('script file'); - component.inputForm.controls['symbol'].setValue('symbol'); + it('should create', () => { + expect(component).toBeTruthy(); + }); - component.onSave(); + it('should call save template', () => { + spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['scriptFile'].setValue('script file'); + component.inputForm.controls['symbol'].setValue('symbol'); - expect(mockedVpcsService.saveTemplate).toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when template name is empty', () => { - spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); - component.inputForm.controls['templateName'].setValue(''); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['scriptFile'].setValue('script file'); - component.inputForm.controls['symbol'].setValue('symbol'); + expect(mockedVpcsService.saveTemplate).toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when template name is empty', () => { + spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); + component.inputForm.controls['templateName'].setValue(''); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['scriptFile'].setValue('script file'); + component.inputForm.controls['symbol'].setValue('symbol'); - expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when default name is empty', () => { - spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue(''); - component.inputForm.controls['scriptFile'].setValue('script file'); - component.inputForm.controls['symbol'].setValue('symbol'); + expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when default name is empty', () => { + spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue(''); + component.inputForm.controls['scriptFile'].setValue('script file'); + component.inputForm.controls['symbol'].setValue('symbol'); - expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when script file is empty', () => { - spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['scriptFile'].setValue(''); - component.inputForm.controls['symbol'].setValue('symbol'); + expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when script file is empty', () => { + spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['scriptFile'].setValue(''); + component.inputForm.controls['symbol'].setValue('symbol'); - expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); - it('should not call save template when symbol path is empty', () => { - spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['scriptFile'].setValue('script file'); - component.inputForm.controls['symbol'].setValue(''); + expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); + }); - component.onSave(); + it('should not call save template when symbol path is empty', () => { + spyOn(mockedVpcsService, 'saveTemplate').and.returnValue(of({} as VpcsTemplate)); + component.inputForm.controls['templateName'].setValue('template name'); + component.inputForm.controls['defaultName'].setValue('default name'); + component.inputForm.controls['scriptFile'].setValue('script file'); + component.inputForm.controls['symbol'].setValue(''); - expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); - }); + component.onSave(); + + expect(mockedVpcsService.saveTemplate).not.toHaveBeenCalled(); + }); }); diff --git a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts index 6b23a04b..76dead8a 100644 --- a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts +++ b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts @@ -1,82 +1,81 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { ToasterService } from '../../../../services/toaster.service'; -import { VpcsService } from '../../../../services/vpcs.service'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; -import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; +import { ServerService } from '../../../../services/server.service'; +import { ToasterService } from '../../../../services/toaster.service'; import { VpcsConfigurationService } from '../../../../services/vpcs-configuration.service'; - +import { VpcsService } from '../../../../services/vpcs.service'; @Component({ - selector: 'app-vpcs-template-details', - templateUrl: './vpcs-template-details.component.html', - styleUrls: ['./vpcs-template-details.component.scss', '../../preferences.component.scss'] + selector: 'app-vpcs-template-details', + templateUrl: './vpcs-template-details.component.html', + styleUrls: ['./vpcs-template-details.component.scss', '../../preferences.component.scss'], }) export class VpcsTemplateDetailsComponent implements OnInit { - server: Server; - vpcsTemplate: VpcsTemplate; - inputForm: FormGroup; - isSymbolSelectionOpened: boolean = false; - consoleTypes: string[] = []; - categories = []; + server: Server; + vpcsTemplate: VpcsTemplate; + inputForm: FormGroup; + isSymbolSelectionOpened: boolean = false; + consoleTypes: string[] = []; + categories = []; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private vpcsService: VpcsService, - private toasterService: ToasterService, - private formBuilder: FormBuilder, - private vpcsConfigurationService: VpcsConfigurationService, - private router: Router - ) { - this.inputForm = this.formBuilder.group({ - templateName: new FormControl('', Validators.required), - defaultName: new FormControl('', Validators.required), - scriptFile: new FormControl('', Validators.required), - symbol: new FormControl('', Validators.required) - }); + constructor( + private route: ActivatedRoute, + private serverService: ServerService, + private vpcsService: VpcsService, + private toasterService: ToasterService, + private formBuilder: FormBuilder, + private vpcsConfigurationService: VpcsConfigurationService, + private router: Router + ) { + this.inputForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + scriptFile: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + }); + } + + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + const template_id = this.route.snapshot.paramMap.get('template_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.getConfiguration(); + this.vpcsService.getTemplate(this.server, template_id).subscribe((vpcsTemplate: VpcsTemplate) => { + this.vpcsTemplate = vpcsTemplate; + }); + }); + } + + getConfiguration() { + this.consoleTypes = this.vpcsConfigurationService.getConsoleTypes(); + this.categories = this.vpcsConfigurationService.getCategories(); + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); + } + + onSave() { + if (this.inputForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.vpcsService.saveTemplate(this.server, this.vpcsTemplate).subscribe((vpcsTemplate: VpcsTemplate) => { + this.toasterService.success('Changes saved'); + }); } + } - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - const template_id = this.route.snapshot.paramMap.get("template_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; + chooseSymbol() { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + } - this.getConfiguration(); - this.vpcsService.getTemplate(this.server, template_id).subscribe((vpcsTemplate: VpcsTemplate) => { - this.vpcsTemplate = vpcsTemplate; - }); - }); - } - - getConfiguration() { - this.consoleTypes = this.vpcsConfigurationService.getConsoleTypes(); - this.categories = this.vpcsConfigurationService.getCategories(); - } - - goBack() { - this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); - } - - onSave() { - if (this.inputForm.invalid) { - this.toasterService.error(`Fill all required fields`); - } else { - this.vpcsService.saveTemplate(this.server, this.vpcsTemplate).subscribe((vpcsTemplate: VpcsTemplate) => { - this.toasterService.success("Changes saved"); - }); - } - } - - chooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - } - - symbolChanged(chosenSymbol: string) { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.vpcsTemplate.symbol = chosenSymbol; - } + symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; + this.vpcsTemplate.symbol = chosenSymbol; + } } diff --git a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html index 1d789d34..3f957137 100644 --- a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html +++ b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html @@ -1,32 +1,46 @@
-
-
-

VPCS node templates

- - -
+
+
+

VPCS node templates

+ +
- -
-
- -
- {{template.name}} - - - - -
-
+
+ +
+
+ +
+ {{ + template.name + }} + + + +
+
+
- - + diff --git a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.spec.ts b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.spec.ts index bcf15acf..eacccc11 100644 --- a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.spec.ts +++ b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.spec.ts @@ -1,60 +1,67 @@ -import { ComponentFixture, async, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatIconModule } from '@angular/material/icon'; import { MatMenuModule } from '@angular/material/menu'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { CommonModule } from '@angular/common'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MockedServerService } from '../../../../services/server.service.spec'; -import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; -import { VpcsService } from '../../../../services/vpcs.service'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; -import { VpcsTemplatesComponent } from './vpcs-templates.component'; +import { ServerService } from '../../../../services/server.service'; +import { MockedServerService } from '../../../../services/server.service.spec'; +import { VpcsService } from '../../../../services/vpcs.service'; import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { VpcsTemplatesComponent } from './vpcs-templates.component'; export class MockedVpcsService { - public getTemplates(server: Server) { - return of([{} as VpcsTemplate]); - } + public getTemplates(server: Server) { + return of([{} as VpcsTemplate]); + } } describe('VpcsTemplatesComponent', () => { - let component: VpcsTemplatesComponent; - let fixture: ComponentFixture; + let component: VpcsTemplatesComponent; + let fixture: ComponentFixture; - let mockedServerService = new MockedServerService; - let mockedVpcsService = new MockedVpcsService; - let activatedRoute = new MockedActivatedRoute().get(); - - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], - providers: [ - { - provide: ActivatedRoute, useValue: activatedRoute - }, - { provide: ServerService, useValue: mockedServerService }, - { provide: VpcsService, useValue: mockedVpcsService } - ], - declarations: [ - VpcsTemplatesComponent - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - })); + let mockedServerService = new MockedServerService(); + let mockedVpcsService = new MockedVpcsService(); + let activatedRoute = new MockedActivatedRoute().get(); - beforeEach(() => { - fixture = TestBed.createComponent(VpcsTemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + CommonModule, + NoopAnimationsModule, + RouterTestingModule.withRoutes([]), + ], + providers: [ + { + provide: ActivatedRoute, + useValue: activatedRoute, + }, + { provide: ServerService, useValue: mockedServerService }, + { provide: VpcsService, useValue: mockedVpcsService }, + ], + declarations: [VpcsTemplatesComponent], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); - it('should create', () => { - expect(component).toBeTruthy(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(VpcsTemplatesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts index a2e570d8..f012409d 100644 --- a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts +++ b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts @@ -1,46 +1,42 @@ -import { Component, OnInit, ViewChild } from "@angular/core"; -import { Server } from '../../../../models/server'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { Server } from '../../../../models/server'; +import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; import { ServerService } from '../../../../services/server.service'; import { VpcsService } from '../../../../services/vpcs.service'; -import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ - selector: 'app-vpcs-templates', - templateUrl: './vpcs-templates.component.html', - styleUrls: ['./vpcs-templates.component.scss', '../../preferences.component.scss'] + selector: 'app-vpcs-templates', + templateUrl: './vpcs-templates.component.html', + styleUrls: ['./vpcs-templates.component.scss', '../../preferences.component.scss'], }) export class VpcsTemplatesComponent implements OnInit { - server: Server; - vpcsTemplates: VpcsTemplate[] = []; - @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; + server: Server; + vpcsTemplates: VpcsTemplate[] = []; + @ViewChild(DeleteTemplateComponent) deleteComponent: DeleteTemplateComponent; - constructor( - private route: ActivatedRoute, - private serverService: ServerService, - private vpcsService: VpcsService - ) {} + constructor(private route: ActivatedRoute, private serverService: ServerService, private vpcsService: VpcsService) {} - ngOnInit() { - const server_id = this.route.snapshot.paramMap.get("server_id"); - this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { - this.server = server; - this.getTemplates(); - }); - } + ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + this.getTemplates(); + }); + } - getTemplates() { - this.vpcsService.getTemplates(this.server).subscribe((vpcsTemplates: VpcsTemplate[]) => { - this.vpcsTemplates = vpcsTemplates.filter((elem) => elem.template_type === 'vpcs' && !elem.builtin); - }); - } + getTemplates() { + this.vpcsService.getTemplates(this.server).subscribe((vpcsTemplates: VpcsTemplate[]) => { + this.vpcsTemplates = vpcsTemplates.filter((elem) => elem.template_type === 'vpcs' && !elem.builtin); + }); + } - deleteTemplate(template: VpcsTemplate) { - this.deleteComponent.deleteItem(template.name, template.template_id); - } + deleteTemplate(template: VpcsTemplate) { + this.deleteComponent.deleteItem(template.name, template.template_id); + } - onDeleteEvent() { - this.getTemplates(); - } + onDeleteEvent() { + this.getTemplates(); + } } diff --git a/src/app/components/project-map/change-hostname-dialog/change-hostname-dialog.component.html b/src/app/components/project-map/change-hostname-dialog/change-hostname-dialog.component.html index d668cfe2..8a903956 100644 --- a/src/app/components/project-map/change-hostname-dialog/change-hostname-dialog.component.html +++ b/src/app/components/project-map/change-hostname-dialog/change-hostname-dialog.component.html @@ -1,21 +1,17 @@ -

Change hostname for node {{name}}

+

Change hostname for node {{ name }}