mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-18 10:46:35 +00:00
Code responsible for adding text refactored
This commit is contained in:
parent
c9b0eca05b
commit
37ec1cc21d
@ -42,7 +42,6 @@ import { SelectionSelectComponent } from './components/selection-select/selectio
|
||||
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 { TextAddingComponent } from './components/text-adding/text-adding.component';
|
||||
import { TextEditingComponent } from './components/text-editing/text-editing.component';
|
||||
import { FontBBoxCalculator } from './helpers/font-bbox-calculator';
|
||||
import { StylesToFontConverter } from './converters/styles-to-font-converter';
|
||||
@ -63,7 +62,6 @@ import { TemporaryTextElementComponent } from './components/temporary-text-eleme
|
||||
D3MapComponent,
|
||||
ExperimentalMapComponent,
|
||||
DrawingResizingComponent,
|
||||
TextAddingComponent,
|
||||
TextEditingComponent,
|
||||
TemporaryTextElementComponent,
|
||||
...ANGULAR_MAP_DECLARATIONS,
|
||||
|
@ -12,6 +12,5 @@
|
||||
<app-selection-control></app-selection-control>
|
||||
<app-selection-select></app-selection-select>
|
||||
<app-temporary-text-element [svg]="svg"></app-temporary-text-element>
|
||||
<app-text-adding></app-text-adding>
|
||||
<app-text-editing></app-text-editing>
|
||||
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
||||
|
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 480 B |
@ -19,9 +19,7 @@ import { Symbol } from '../../../models/symbol';
|
||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||
import { MapSettingsManager } from '../../managers/map-settings-manager';
|
||||
import { TextEditingTool } from '../../tools/text-editing-tool';
|
||||
import { TextAddingComponent } from '../text-adding/text-adding.component';
|
||||
import { Server } from '../../../models/server';
|
||||
import { TextAddingTool } from '../../tools/text-adding-tool';
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
|
||||
|
||||
@ -41,7 +39,6 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() height = 600;
|
||||
|
||||
@ViewChild('svg') svgRef: ElementRef;
|
||||
@ViewChild(TextAddingComponent) textAddingComponent: TextAddingComponent;
|
||||
|
||||
private parentNativeElement: any;
|
||||
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
||||
@ -65,7 +62,6 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
protected interfaceLabelWidget: InterfaceLabelWidget,
|
||||
protected selectionToolWidget: SelectionTool,
|
||||
protected movingToolWidget: MovingTool,
|
||||
protected textAddingToolWidget: TextAddingTool,
|
||||
protected textEditingToolWidget: TextEditingTool,
|
||||
public graphLayout: GraphLayout,
|
||||
private toolsService: ToolsService
|
||||
@ -114,13 +110,6 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
this.subscriptions.push(
|
||||
this.toolsService.isTextAddingToolActivated.subscribe((value: boolean) => {
|
||||
//this.textAddingToolWidget.setEnabled(value);
|
||||
this.mapChangeDetectorRef.detectChanges();
|
||||
})
|
||||
);
|
||||
|
||||
this.subscriptions.push(
|
||||
this.toolsService.isTextEditingToolActivated.subscribe((value: boolean) => {
|
||||
this.textEditingToolWidget.setEnabled(value);
|
||||
|
@ -13,10 +13,9 @@ export class TemporaryTextElementComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
|
||||
//should cover all style variables that can change
|
||||
private leftPosition: string;
|
||||
private topPosition: string;
|
||||
private innerText: string;
|
||||
private leftPosition: string = '0px';
|
||||
private topPosition: string = '0px';
|
||||
private innerText: string = '';
|
||||
private isActive: boolean = true;
|
||||
private mapListener: Function;
|
||||
private textListener: Function;
|
||||
@ -25,14 +24,11 @@ export class TemporaryTextElementComponent implements OnInit, OnDestroy {
|
||||
constructor(
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private toolsService: ToolsService
|
||||
){
|
||||
this.leftPosition = '100px';
|
||||
this.topPosition = '100px';
|
||||
this.innerText = '';
|
||||
}
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
this.toolsService.isTextAddingToolActivated.subscribe((isActive: boolean) => {
|
||||
this.isActive = isActive;
|
||||
isActive ? this.activate() : this.decativate()
|
||||
});
|
||||
}
|
||||
@ -45,11 +41,10 @@ export class TemporaryTextElementComponent implements OnInit, OnDestroy {
|
||||
this.temporaryTextElement.nativeElement.focus();
|
||||
|
||||
let textListener = () => {
|
||||
console.log("textListener: ", this.innerText);
|
||||
this.drawingsEventSource.textAdded.emit(new TextAddedDataEvent(this.innerText.replace(/\n$/, ""), event.clientX, event.clientY));
|
||||
this.drawingsEventSource.textAdded.emit(new TextAddedDataEvent(this.temporaryTextElement.nativeElement.innerText.replace(/\n$/, ""), event.clientX, event.clientY));
|
||||
this.svg.removeEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
this.temporaryTextElement.nativeElement.removeEventListener('focusout', this.textListener);
|
||||
this.innerText = '';
|
||||
this.isActive = false;
|
||||
}
|
||||
this.textListener = textListener;
|
||||
this.temporaryTextElement.nativeElement.addEventListener('focusout', this.textListener);
|
||||
@ -64,6 +59,6 @@ export class TemporaryTextElementComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnDestroy(){
|
||||
|
||||
this.toolsService.isTextAddingToolActivated.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
import { Component, OnInit, OnDestroy } from "@angular/core";
|
||||
import { select } from 'd3-selection';
|
||||
import { Context } from "../../models/context";
|
||||
import { TextAddingTool } from '../../tools/text-adding-tool';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { TextAddedDataEvent } from '../../events/event-source';
|
||||
|
||||
@Component({
|
||||
selector: 'app-text-adding',
|
||||
template: `<ng-content></ng-content>`,
|
||||
styleUrls: ['./text-adding.component.scss']
|
||||
})
|
||||
export class TextAddingComponent implements OnInit, OnDestroy {
|
||||
textAddingFinished: Subscription;
|
||||
|
||||
constructor(
|
||||
private textAddingTool: TextAddingTool,
|
||||
private drawingEventSource: DrawingsEventSource
|
||||
){}
|
||||
|
||||
ngOnInit() {
|
||||
this.textAddingFinished = this.textAddingTool.addingFinished.subscribe((evt: TextAddedDataEvent) => {
|
||||
this.drawingEventSource.textAdded.emit(evt);
|
||||
})
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.textAddingFinished.unsubscribe();
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import { DrawingsWidget } from './widgets/drawings';
|
||||
import { DrawingLineWidget } from './widgets/drawing-line';
|
||||
import { SelectionTool } from './tools/selection-tool';
|
||||
import { MovingTool } from './tools/moving-tool';
|
||||
import {TextAddingTool} from './tools/text-adding-tool';
|
||||
import {TextEditingTool} from './tools/text-editing-tool';
|
||||
import { LayersWidget } from './widgets/layers';
|
||||
import { LinkWidget } from './widgets/link';
|
||||
@ -30,7 +29,6 @@ export const D3_MAP_IMPORTS = [
|
||||
DrawingLineWidget,
|
||||
SelectionTool,
|
||||
MovingTool,
|
||||
TextAddingTool,
|
||||
TextEditingTool,
|
||||
LayersWidget,
|
||||
LinkWidget,
|
||||
|
@ -1,74 +0,0 @@
|
||||
import { Injectable, EventEmitter } from "@angular/core";
|
||||
import { TextAddedDataEvent } from '../events/event-source';
|
||||
import { DrawingsEventSource } from '../events/drawings-event-source';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class TextAddingTool {
|
||||
private listener: Function;
|
||||
private temporaryElement: HTMLDivElement;
|
||||
public addingFinished = new EventEmitter<any>();
|
||||
|
||||
constructor(
|
||||
private drawingEventSource: DrawingsEventSource,
|
||||
){}
|
||||
|
||||
public setEnabled(enabled){
|
||||
// if (enabled){
|
||||
// this.activate();
|
||||
// } else {
|
||||
// this.deactivate();
|
||||
// }
|
||||
}
|
||||
|
||||
private deactivate(){
|
||||
var map = document.getElementsByClassName('map')[0];
|
||||
map.removeEventListener('click', this.listener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
|
||||
private activate(){
|
||||
var map = document.getElementsByClassName('map')[0];
|
||||
|
||||
let addTextListener = (event: MouseEvent) => {
|
||||
this.temporaryElement = this.getTemporaryElement(event.clientX, event.clientY);
|
||||
document.body.appendChild(this.temporaryElement);
|
||||
this.temporaryElement.focus();
|
||||
document.body.style.cursor = "text";
|
||||
|
||||
this.temporaryElement.addEventListener("focusout", () => {
|
||||
let innerText = this.temporaryElement.innerText;
|
||||
this.addingFinished.emit(new TextAddedDataEvent(innerText.replace(/\n$/, ""), event.clientX, event.clientY));
|
||||
|
||||
this.drawingEventSource.textSaved.subscribe((evt:boolean) => {
|
||||
if(evt){
|
||||
this.temporaryElement.remove();
|
||||
document.body.style.cursor = "default";
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
map.removeEventListener('click', this.listener as EventListenerOrEventListenerObject);
|
||||
this.listener = addTextListener;
|
||||
map.addEventListener('click', this.listener as EventListenerOrEventListenerObject, {once : true});
|
||||
}
|
||||
|
||||
private getTemporaryElement(x:number, y:number): HTMLDivElement{
|
||||
var elem = document.createElement('div');
|
||||
elem.className = "temporaryElement";
|
||||
elem.style.paddingLeft = "4px";
|
||||
elem.style.width = "fit-content";
|
||||
elem.style.left = x.toString() + 'px';
|
||||
elem.style.top = y.toString() + 'px';
|
||||
elem.style.position = "absolute";
|
||||
elem.style.zIndex = "99";
|
||||
elem.style.fontFamily = "Noto Sans";
|
||||
elem.style.fontSize = "11pt";
|
||||
elem.style.fontWeight = "bold";
|
||||
elem.style.color = "#000000";
|
||||
elem.setAttribute("contenteditable", "true");
|
||||
elem.innerText = "";
|
||||
|
||||
return elem;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
import { TextAddedComponent } from "./text-added.component";
|
||||
import { ComponentFixture, async, TestBed } from '@angular/core/testing';
|
||||
import { DrawingService } from '../../../services/drawing.service';
|
||||
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 { 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';
|
||||
|
||||
describe('TextAddedComponent', () => {
|
||||
let component: TextAddedComponent;
|
||||
let fixture: ComponentFixture<TextAddedComponent>;
|
||||
let mockedDrawingService = new MockedDrawingService;
|
||||
let mockedDrawingsDataSource = new MockedDrawingsDataSource;
|
||||
let mockedDrawingsEventSource = new DrawingsEventSource;
|
||||
let mockedDrawingsFactory = new DefaultDrawingsFactory(new TextElementFactory,
|
||||
new EllipseElementFactory, new RectangleElementFactory, new LineElementFactory);
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{ provide: DrawingService, useValue: mockedDrawingService },
|
||||
{ provide: DrawingsDataSource, useValue: mockedDrawingsDataSource },
|
||||
{ provide: DrawingsEventSource, useValue: mockedDrawingsEventSource },
|
||||
{ provide: DefaultDrawingsFactory, useValue: mockedDrawingsFactory },
|
||||
{ provide: MapDrawingToSvgConverter, useClass: MapDrawingToSvgConverter },
|
||||
{ provide: Context, useClass: Context}
|
||||
],
|
||||
declarations: [
|
||||
TextAddedComponent
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TextAddedComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should call drawing service when text added', () => {
|
||||
component.project = { project_id: "sampleId" } as Project;
|
||||
const textAddedDataEvent = new TextAddedDataEvent("savedText", 0 ,0);
|
||||
spyOn(mockedDrawingService, 'add').and.returnValue( Observable.of({}));
|
||||
|
||||
mockedDrawingsEventSource.textAdded.emit(textAddedDataEvent);
|
||||
|
||||
expect(mockedDrawingService.add).toHaveBeenCalled();
|
||||
});
|
||||
});
|
@ -10,6 +10,7 @@ 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';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -28,7 +29,8 @@ export class TextAddedComponent implements OnInit, OnDestroy{
|
||||
private drawingsDataSource: DrawingsDataSource,
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private drawingsFactory: DefaultDrawingsFactory,
|
||||
private mapDrawingToSvgConverter: MapDrawingToSvgConverter
|
||||
private mapDrawingToSvgConverter: MapDrawingToSvgConverter,
|
||||
private context: Context
|
||||
){}
|
||||
|
||||
ngOnInit(){
|
||||
@ -36,14 +38,12 @@ export class TextAddedComponent implements OnInit, OnDestroy{
|
||||
}
|
||||
|
||||
onTextAdded(evt: TextAddedDataEvent){
|
||||
console.log(evt);
|
||||
|
||||
let drawing = this.drawingsFactory.getDrawingMock("text");
|
||||
(drawing.element as TextElement).text = "evtsavedText";
|
||||
(drawing.element as TextElement).text = evt.savedText;
|
||||
let svgText = this.mapDrawingToSvgConverter.convert(drawing);
|
||||
|
||||
this.drawingService
|
||||
.add(this.server, this.project.project_id, -55, -400, svgText)
|
||||
.add(this.server, this.project.project_id, evt.x - this.context.getZeroZeroTransformationPoint().x, evt.y - this.context.getZeroZeroTransformationPoint().y, svgText)
|
||||
.subscribe((serverDrawing: Drawing) => {
|
||||
this.drawingsDataSource.add(serverDrawing);
|
||||
this.drawingSaved.emit(true);
|
||||
|
@ -8,7 +8,6 @@ import { Server } from '../../../models/server';
|
||||
import { MapDrawing } from '../../../cartography/models/map/map-drawing';
|
||||
import { Drawing } from '../../../cartography/models/drawing';
|
||||
import { Context } from '../../../cartography/models/context';
|
||||
import { TextElement } from '../../../cartography/models/drawings/text-element';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -36,11 +35,9 @@ export class AddDrawingComponent implements OnChanges {
|
||||
if(changes['selectedDrawing'] && !changes['selectedDrawing'].isFirstChange()){
|
||||
if(this.availableDrawings.includes(changes['selectedDrawing'].currentValue)){
|
||||
this.addDrawing(changes['selectedDrawing'].currentValue);
|
||||
} else if (changes['selectedDrawing'].currentValue === "text") {
|
||||
//this.addText();
|
||||
} else {
|
||||
} else if (!(changes['selectedDrawing'].currentValue === "text")) {
|
||||
document.getElementsByClassName('map')[0].removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,50 +62,4 @@ export class AddDrawingComponent implements OnChanges {
|
||||
this.drawListener = listener;
|
||||
map.addEventListener('click', this.drawListener as EventListenerOrEventListenerObject, {once : true});
|
||||
}
|
||||
|
||||
addText(){
|
||||
let addTextListener = (event: MouseEvent) => {
|
||||
let textBox = document.createElement('div');
|
||||
textBox.style.width = "fit-content";
|
||||
textBox.style.left = event.clientX.toString() + 'px';
|
||||
textBox.style.top = (event.clientY - 10).toString() + 'px';
|
||||
textBox.style.position = "absolute";
|
||||
textBox.style.zIndex = "99";
|
||||
|
||||
textBox.style.fontFamily = "Noto Sans";
|
||||
textBox.style.fontSize = "11pt";
|
||||
textBox.style.fontWeight = "bold";
|
||||
textBox.style.color = "#000000";
|
||||
|
||||
textBox.setAttribute("contenteditable", "true");
|
||||
|
||||
document.body.appendChild(textBox);
|
||||
textBox.innerText = "";
|
||||
textBox.focus();
|
||||
document.body.style.cursor = "text";
|
||||
|
||||
textBox.addEventListener("focusout", () => {
|
||||
let savedText = textBox.innerText;
|
||||
|
||||
let drawing = this.drawingsFactory.getDrawingMock("text");
|
||||
(drawing.element as TextElement).text = savedText;
|
||||
let svgText = this.mapDrawingToSvgConverter.convert(drawing);
|
||||
|
||||
this.drawingService
|
||||
.add(this.server, this.project.project_id, event.clientX - this.context.getZeroZeroTransformationPoint().x, event.clientY - this.context.getZeroZeroTransformationPoint().y, svgText)
|
||||
.subscribe((serverDrawing: Drawing) => {
|
||||
document.body.style.cursor = "default";
|
||||
textBox.remove();
|
||||
|
||||
this.drawingsDataSource.add(serverDrawing);
|
||||
this.drawingSaved.emit(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let map = document.getElementsByClassName('map')[0];
|
||||
map.removeEventListener('click', this.drawListener as EventListenerOrEventListenerObject);
|
||||
this.drawListener = addTextListener;
|
||||
map.addEventListener('click', this.drawListener as EventListenerOrEventListenerObject, {once : true});
|
||||
}
|
||||
}
|
||||
|
@ -144,17 +144,20 @@
|
||||
<app-draw-link-tool *ngIf="tools.draw_link"></app-draw-link-tool>
|
||||
|
||||
<app-add-drawing
|
||||
[project]="project"
|
||||
[server]="server"
|
||||
[project]="project"
|
||||
[selectedDrawing]="selectedDrawing"
|
||||
(drawingSaved)="onDrawingSaved($event)">
|
||||
</app-add-drawing>
|
||||
|
||||
<app-drawing-dragged [server]="server"></app-drawing-dragged>
|
||||
<app-drawing-resized [server]="server"></app-drawing-resized>
|
||||
<app-interface-label-dragged [server]="server"></app-interface-label-dragged>
|
||||
<app-link-created [server]="server" [project]="project"></app-link-created>
|
||||
<app-node-dragged [server]="server"></app-node-dragged>
|
||||
<app-node-label-dragged [server]="server"></app-node-label-dragged>
|
||||
<app-text-added [server]="server" [project]="project"></app-text-added>
|
||||
<app-text-added
|
||||
[server]="server"
|
||||
[project]="project"
|
||||
(drawingSaved)="onDrawingSaved($event)"
|
||||
></app-text-added>
|
||||
<app-text-edited [server]="server"></app-text-edited>
|
||||
|
Loading…
Reference in New Issue
Block a user