mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-04 00:10:47 +00:00
Refreshing UI (#1253)
* Update font-fixer.ts * Update interface-status.ts * Updating project map UI * Updating templates menu * Fixing tests * Update karma.conf.js
This commit is contained in:
parent
2b834768c6
commit
8874e7efbc
@ -16,8 +16,8 @@ describe('FontFixer', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
expect(fixer.fix(font)).toEqual({
|
expect(fixer.fix(font)).toEqual({
|
||||||
font_family: 'Noto Sans',
|
font_family: 'Arial',
|
||||||
font_size: 11,
|
font_size: 12,
|
||||||
font_weight: 'bold',
|
font_weight: 'bold',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -39,12 +39,12 @@ describe('FontFixer', () => {
|
|||||||
it('should fix TypeWriter font and 10px size in styles', () => {
|
it('should fix TypeWriter font and 10px size in styles', () => {
|
||||||
const styles = 'font-family: TypeWriter; font-size: 10px; font-weight: bold';
|
const styles = 'font-family: TypeWriter; font-size: 10px; font-weight: bold';
|
||||||
|
|
||||||
expect(fixer.fixStyles(styles)).toEqual('font-family:Noto Sans;font-size:11px;font-weight:bold');
|
expect(fixer.fixStyles(styles)).toEqual('font-family:Arial;font-size:12px;font-weight:bold');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fix TypeWriter font and 10px size in styles with quotes', () => {
|
it('should fix TypeWriter font and 10px size in styles with quotes', () => {
|
||||||
const styles = 'font-family: "TypeWriter"; font-size: 10px; font-weight: bold';
|
const styles = 'font-family: "TypeWriter"; font-size: 10px; font-weight: bold';
|
||||||
|
|
||||||
expect(fixer.fixStyles(styles)).toEqual('font-family:Noto Sans;font-size:11px;font-weight:bold');
|
expect(fixer.fixStyles(styles)).toEqual('font-family:Arial;font-size:12px;font-weight:bold');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,8 +9,8 @@ import { Font } from '../models/font';
|
|||||||
export class FontFixer {
|
export class FontFixer {
|
||||||
static DEFAULT_FONT = 'TypeWriter';
|
static DEFAULT_FONT = 'TypeWriter';
|
||||||
static DEFAULT_SIZE = 10;
|
static DEFAULT_SIZE = 10;
|
||||||
static REPLACE_BY_FONT = 'Noto Sans';
|
static REPLACE_BY_FONT = 'Arial';
|
||||||
static REPLACE_BY_SIZE = 11;
|
static REPLACE_BY_SIZE = 12;
|
||||||
|
|
||||||
public fix(font: Font): Font {
|
public fix(font: Font): Font {
|
||||||
if (font.font_family === FontFixer.DEFAULT_FONT && font.font_size === FontFixer.DEFAULT_SIZE) {
|
if (font.font_family === FontFixer.DEFAULT_FONT && font.font_size === FontFixer.DEFAULT_SIZE) {
|
||||||
|
@ -42,7 +42,7 @@ describe('TextDrawingWidget', () => {
|
|||||||
const text_element = drew.nodes()[0];
|
const text_element = drew.nodes()[0];
|
||||||
expect(text_element.innerHTML).toEqual('<tspan xml:space="preserve" x="0" dy="0em">THIS IS TEXT</tspan>');
|
expect(text_element.innerHTML).toEqual('<tspan xml:space="preserve" x="0" dy="0em">THIS IS TEXT</tspan>');
|
||||||
expect(text_element.getAttribute('fill')).toEqual('#000000');
|
expect(text_element.getAttribute('fill')).toEqual('#000000');
|
||||||
expect(text_element.getAttribute('style')).toEqual('font-family: "Noto Sans"; font-size: 11pt; font-weight: bold');
|
expect(text_element.getAttribute('style')).toEqual('font-family: "Arial"; font-size: 12pt; font-weight: bold');
|
||||||
expect(text_element.getAttribute('text-decoration')).toEqual('line-through');
|
expect(text_element.getAttribute('text-decoration')).toEqual('line-through');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -97,9 +97,9 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
.attr('rx', 8)
|
.attr('rx', 8)
|
||||||
.attr('ry', 8)
|
.attr('ry', 8)
|
||||||
.style('fill', 'white')
|
.style('fill', '#c7ffdf')
|
||||||
.attr('stroke', '#2ecc71')
|
.attr('stroke', '#2ecc71')
|
||||||
.attr('stroke-width', 3);
|
.attr('stroke-width', 2);
|
||||||
status_started.exit().remove();
|
status_started.exit().remove();
|
||||||
const status_started_label = link_group
|
const status_started_label = link_group
|
||||||
.selectAll<SVGTextElement, LinkStatus>('text.status_started_label')
|
.selectAll<SVGTextElement, LinkStatus>('text.status_started_label')
|
||||||
@ -111,7 +111,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.text((ls: LinkStatus) => ls.port)
|
.text((ls: LinkStatus) => ls.port)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
.attr('fill', `black`);
|
.attr('fill', `#0e9647`);
|
||||||
status_started_label.exit().remove();
|
status_started_label.exit().remove();
|
||||||
|
|
||||||
const status_stopped = link_group
|
const status_stopped = link_group
|
||||||
@ -129,9 +129,9 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
.attr('y', (ls: LinkStatus) => ls.y - 10)
|
||||||
.attr('rx', 8)
|
.attr('rx', 8)
|
||||||
.attr('ry', 8)
|
.attr('ry', 8)
|
||||||
.style('fill', 'white')
|
.style('fill', '#ffe3e3')
|
||||||
.attr('stroke', 'red')
|
.attr('stroke', 'red')
|
||||||
.attr('stroke-width', 3);
|
.attr('stroke-width', 2);
|
||||||
status_stopped.exit().remove();
|
status_stopped.exit().remove();
|
||||||
const status_stopped_label = link_group
|
const status_stopped_label = link_group
|
||||||
.selectAll<SVGTextElement, LinkStatus>('text.status_stopped_label')
|
.selectAll<SVGTextElement, LinkStatus>('text.status_stopped_label')
|
||||||
@ -143,7 +143,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.text((ls: LinkStatus) => ls.port)
|
.text((ls: LinkStatus) => ls.port)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
.attr('fill', `black`);
|
.attr('fill', `red`);
|
||||||
status_stopped_label.exit().remove();
|
status_stopped_label.exit().remove();
|
||||||
|
|
||||||
const status_suspended = link_group
|
const status_suspended = link_group
|
||||||
@ -162,8 +162,8 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.attr('rx', 8)
|
.attr('rx', 8)
|
||||||
.attr('ry', 8)
|
.attr('ry', 8)
|
||||||
.style('fill', 'white')
|
.style('fill', 'white')
|
||||||
.attr('stroke', '#FFFF00')
|
.attr('stroke', '#fffbc3')
|
||||||
.attr('stroke-width', 3);
|
.attr('stroke-width', 2);
|
||||||
status_suspended.exit().remove();
|
status_suspended.exit().remove();
|
||||||
const status_suspended_label = link_group
|
const status_suspended_label = link_group
|
||||||
.selectAll<SVGTextElement, LinkStatus>('text.status_suspended_label')
|
.selectAll<SVGTextElement, LinkStatus>('text.status_suspended_label')
|
||||||
@ -175,7 +175,7 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
.text((ls: LinkStatus) => ls.port)
|
.text((ls: LinkStatus) => ls.port)
|
||||||
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
.attr('x', (ls: LinkStatus) => ls.x - 25)
|
||||||
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
.attr('y', (ls: LinkStatus) => ls.y + 5)
|
||||||
.attr('fill', `black`);
|
.attr('fill', `#6b5633`);
|
||||||
status_suspended_label.exit().remove();
|
status_suspended_label.exit().remove();
|
||||||
} else {
|
} else {
|
||||||
const status_started = link_group
|
const status_started = link_group
|
||||||
|
@ -67,6 +67,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
<button
|
||||||
|
class="map-settings-button"
|
||||||
|
matTooltip="Project Map Settings"
|
||||||
|
matTooltipClass="custom-tooltip"
|
||||||
|
mat-icon-button
|
||||||
|
[matMenuTriggerFor]="viewMenu">
|
||||||
|
<mat-icon>view_module</mat-icon>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
matTooltip="Toggle topology/servers summary"
|
matTooltip="Toggle topology/servers summary"
|
||||||
matTooltipClass="custom-tooltip"
|
matTooltipClass="custom-tooltip"
|
||||||
@ -83,39 +91,27 @@
|
|||||||
|
|
||||||
<!-- GNS3 menu -->
|
<!-- GNS3 menu -->
|
||||||
<mat-menu #mainMenu="matMenu" [overlapTrigger]="false">
|
<mat-menu #mainMenu="matMenu" [overlapTrigger]="false">
|
||||||
|
<button mat-menu-item [matMenuTriggerFor]="projectMenu">
|
||||||
|
<mat-icon>insert_drive_file</mat-icon>
|
||||||
|
<span>Project settings</span>
|
||||||
|
</button>
|
||||||
<button mat-menu-item [routerLink]="['/server', server.id, 'projects']">
|
<button mat-menu-item [routerLink]="['/server', server.id, 'projects']">
|
||||||
<mat-icon>work</mat-icon>
|
<mat-icon>work</mat-icon>
|
||||||
<span>Go to projects</span>
|
<span>Projects</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item [routerLink]="['/servers']">
|
<button mat-menu-item [routerLink]="['/servers']">
|
||||||
<mat-icon>developer_board</mat-icon>
|
<mat-icon>developer_board</mat-icon>
|
||||||
<span>Go to servers</span>
|
<span>Servers</span>
|
||||||
</button>
|
|
||||||
<button mat-menu-item routerLink="/server/{{ server.id }}/preferences">
|
|
||||||
<mat-icon>settings_applications</mat-icon>
|
|
||||||
<span>Go to preferences</span>
|
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item routerLink="/server/{{ server.id }}/systemstatus">
|
<button mat-menu-item routerLink="/server/{{ server.id }}/systemstatus">
|
||||||
<mat-icon>info</mat-icon>
|
<mat-icon>data_usage</mat-icon>
|
||||||
<span>Go to system status</span>
|
<span>System Status</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item routerLink="/settings">
|
<button mat-menu-item routerLink="/settings">
|
||||||
<mat-icon>settings</mat-icon>
|
<mat-icon>settings</mat-icon>
|
||||||
<span>Go to settings</span>
|
<span>Settings</span>
|
||||||
</button>
|
|
||||||
<button mat-menu-item (click)="addNewTemplate()">
|
|
||||||
<mat-icon>control_point</mat-icon>
|
|
||||||
<span>New template</span>
|
|
||||||
</button>
|
</button>
|
||||||
<app-import-appliance [server]="server" [project]="project"></app-import-appliance>
|
<app-import-appliance [server]="server" [project]="project"></app-import-appliance>
|
||||||
<button mat-menu-item [matMenuTriggerFor]="projectMenu">
|
|
||||||
<mat-icon>settings</mat-icon>
|
|
||||||
<span>Project settings</span>
|
|
||||||
</button>
|
|
||||||
<button mat-menu-item [matMenuTriggerFor]="viewMenu">
|
|
||||||
<mat-icon>view_module</mat-icon>
|
|
||||||
<span>Map settings</span>
|
|
||||||
</button>
|
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<!-- Project Settings sub-menu -->
|
<!-- Project Settings sub-menu -->
|
||||||
|
@ -73,6 +73,10 @@ g.node:hover {
|
|||||||
font-size: 28px !important;
|
font-size: 28px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map-settings-button mat-icon {
|
||||||
|
font-size: 22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.selected {
|
.selected {
|
||||||
background: rgba(0, 151, 167, 0.1);
|
background: rgba(0, 151, 167, 0.1);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<h1 mat-dialog-title>Add a node</h1>
|
<h1 mat-dialog-title>Insert New Node</h1>
|
||||||
<button
|
<button
|
||||||
mat-button
|
mat-button
|
||||||
class="top-button"
|
class="top-button"
|
||||||
|
@ -10,63 +10,95 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<mat-menu #mainMenu="matMenu">
|
<mat-menu #mainMenu="matMenu">
|
||||||
<button mat-menu-item (click)="openDialog()">
|
<div class="templateMenu">
|
||||||
<mat-icon>add_to_queue</mat-icon>
|
<div class="templateMenuHeader">
|
||||||
<span>Open dialog to configure</span>
|
<button mat-menu-item (click)="openDialog()">
|
||||||
</button>
|
<mat-icon>add_to_queue</mat-icon>
|
||||||
|
<span>
|
||||||
|
Insert New Node...
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button mat-menu-item (click)="addNewTemplate()">
|
||||||
|
<mat-icon>library_add</mat-icon>
|
||||||
|
<span>
|
||||||
|
New Template...
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-form-field (click)="$event.stopPropagation()" class="form-field" floatPlaceholder="never">
|
<div class="templateFilterBar">
|
||||||
<input
|
<mat-form-field (click)="$event.stopPropagation()" class="form-field" floatPlaceholder="never">
|
||||||
matInput
|
<input
|
||||||
placeholder="Search by name"
|
matInput
|
||||||
(keyup)="filterTemplates($event)"
|
placeholder="Filter by name"
|
||||||
[(ngModel)]="searchText"
|
search="search"
|
||||||
[ngModelOptions]="{ standalone: true }"
|
(keyup)="filterTemplates($event)"
|
||||||
/>
|
[(ngModel)]="searchText"
|
||||||
</mat-form-field>
|
[ngModelOptions]="{ standalone: true }"
|
||||||
<mat-form-field (click)="$event.stopPropagation()" class="form-field">
|
/>
|
||||||
<mat-select
|
<mat-icon class="searchIcon" matSuffix>search</mat-icon>
|
||||||
[ngModelOptions]="{ standalone: true }"
|
</mat-form-field>
|
||||||
placeholder="Filter templates by type"
|
<mat-form-field (click)="$event.stopPropagation()" class="form-field">
|
||||||
(selectionChange)="filterTemplates($event)"
|
<mat-select
|
||||||
[(ngModel)]="selectedType"
|
[ngModelOptions]="{ standalone: true }"
|
||||||
>
|
placeholder="Filter by type"
|
||||||
<mat-option *ngFor="let type of templateTypes" [value]="type">
|
(selectionChange)="filterTemplates($event)"
|
||||||
{{ type }}
|
[(ngModel)]="selectedType"
|
||||||
</mat-option>
|
>
|
||||||
</mat-select>
|
<mat-option *ngFor="let type of templateTypes" [value]="type">
|
||||||
</mat-form-field>
|
{{ type }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<div class="templateList">
|
<div class="templateList">
|
||||||
<mat-list-item *ngFor="let template of filteredTemplates; let i = index">
|
<mat-list-item *ngFor="let template of filteredTemplates; let i = index">
|
||||||
<span *ngIf="i % 4 === 0" class="templateRow">
|
<span *ngIf="i % 4 === 0" class="templateRow">
|
||||||
<span class="templateIcon">
|
<span class="templateIcon">
|
||||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i])">
|
<div
|
||||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i])" />
|
mwlDraggable
|
||||||
</div>
|
(dragStart)="dragStart($event)"
|
||||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i].name }}</div>
|
(dragEnd)="dragEnd($event, filteredTemplates[i])"
|
||||||
</span>
|
class="iconContainer">
|
||||||
<span *ngIf="filteredTemplates[i + 1]" class="templateIcon">
|
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i])" />
|
||||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i + 1])">
|
</div>
|
||||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 1])" />
|
<div class="templateText">{{ filteredTemplates[i].name }}</div>
|
||||||
</div>
|
</span>
|
||||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i + 1].name }}</div>
|
<span *ngIf="filteredTemplates[i + 1]" class="templateIcon">
|
||||||
</span>
|
<div
|
||||||
<span *ngIf="filteredTemplates[i + 2]" class="templateIcon">
|
mwlDraggable
|
||||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i + 2])">
|
(dragStart)="dragStart($event)"
|
||||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 2])" />
|
(dragEnd)="dragEnd($event, filteredTemplates[i + 1])"
|
||||||
</div>
|
class="iconContainer">
|
||||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i + 2].name }}</div>
|
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 1])" />
|
||||||
</span>
|
</div>
|
||||||
<span *ngIf="filteredTemplates[i + 3]" class="templateIcon">
|
<div class="templateText">{{ filteredTemplates[i + 1].name }}</div>
|
||||||
<div mwlDraggable (dragStart)="dragStart($event)" (dragEnd)="dragEnd($event, filteredTemplates[i + 3])">
|
</span>
|
||||||
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 3])" />
|
<span *ngIf="filteredTemplates[i + 2]" class="templateIcon">
|
||||||
</div>
|
<div
|
||||||
<div [ngClass]="{ templateText: !isLightThemeEnabled, lightTemplateText: isLightThemeEnabled }">{{ filteredTemplates[i + 3].name }}</div>
|
mwlDraggable
|
||||||
</span>
|
(dragStart)="dragStart($event)"
|
||||||
</span>
|
(dragEnd)="dragEnd($event, filteredTemplates[i + 2])"
|
||||||
</mat-list-item>
|
class="iconContainer">
|
||||||
</div>
|
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 2])" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="templateText">{{ filteredTemplates[i + 2].name }}</div>
|
||||||
|
</span>
|
||||||
|
<span *ngIf="filteredTemplates[i + 3]" class="templateIcon">
|
||||||
|
<div
|
||||||
|
mwlDraggable
|
||||||
|
(dragStart)="dragStart($event)"
|
||||||
|
(dragEnd)="dragEnd($event, filteredTemplates[i + 3])"
|
||||||
|
class="iconContainer">
|
||||||
|
<img class="image" [src]="getImageSourceForTemplate(filteredTemplates[i + 3])" />
|
||||||
|
</div>
|
||||||
|
<div class="templateText">{{ filteredTemplates[i + 3].name }}</div>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</mat-list-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</mat-menu>
|
</mat-menu>
|
@ -1,6 +1,7 @@
|
|||||||
::ng-deep .mat-menu-panel {
|
::ng-deep .mat-menu-panel {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
max-height: 500px;
|
max-height: 640px;
|
||||||
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
@ -8,6 +9,26 @@
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
scrollbar-color: darkgrey #263238;
|
scrollbar-color: darkgrey #263238;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.templateMenuHeader {
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.templateFilterBar {
|
||||||
|
padding: 10px 2%;
|
||||||
|
background-color: rgba(0,0,0,0.2);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.templateFilterBar > .form-field {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.templateFilterBar .searchIcon {
|
||||||
|
position: relative;
|
||||||
|
top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
@ -24,20 +45,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-field {
|
.form-field {
|
||||||
width: 90%;
|
width: 44%;
|
||||||
margin-left: 5%;
|
margin-left: 3%;
|
||||||
margin-right: 5%;
|
margin-right: 3%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
width: 65px;
|
display: inline-block;
|
||||||
height: 65px;
|
width: 55px;
|
||||||
|
height: 55px;
|
||||||
filter: invert(0);
|
filter: invert(0);
|
||||||
--webkit-filter: invert(0) !important;
|
--webkit-filter: invert(0) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.templateList {
|
.templateList {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.templateRow {
|
.templateRow {
|
||||||
@ -49,12 +72,24 @@
|
|||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lightTemplateText {
|
.templateIcon {
|
||||||
word-wrap: break-word;
|
width: 90px !important;
|
||||||
color: black;
|
padding: 2px 5px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.templateIcon {
|
.templateIcon > .iconContainer {
|
||||||
width: 80px !important;
|
display: inline-flex;
|
||||||
padding: 10px;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
.templateIcon > .iconContainer:hover {
|
||||||
|
background-color: rgba(237, 246, 231, 0.08);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
|
||||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ThemeService } from '../../services/theme.service';
|
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { Project } from '../../models/project';
|
import { Project } from '../../models/project';
|
||||||
import { Server } from '../../models/server';
|
import { Server } from '../../models/server';
|
||||||
@ -10,6 +8,7 @@ import { MapScaleService } from '../../services/mapScale.service';
|
|||||||
import { SymbolService } from '../../services/symbol.service';
|
import { SymbolService } from '../../services/symbol.service';
|
||||||
import { TemplateService } from '../../services/template.service';
|
import { TemplateService } from '../../services/template.service';
|
||||||
import { NodeAddedEvent, TemplateListDialogComponent } from './template-list-dialog/template-list-dialog.component';
|
import { NodeAddedEvent, TemplateListDialogComponent } from './template-list-dialog/template-list-dialog.component';
|
||||||
|
import { NewTemplateDialogComponent } from '../project-map/new-template-dialog/new-template-dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-template',
|
selector: 'app-template',
|
||||||
@ -20,7 +19,7 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
|||||||
@Input() server: Server;
|
@Input() server: Server;
|
||||||
@Input() project: Project;
|
@Input() project: Project;
|
||||||
@Output() onNodeCreation = new EventEmitter<any>();
|
@Output() onNodeCreation = new EventEmitter<any>();
|
||||||
overlay;
|
|
||||||
templates: Template[] = [];
|
templates: Template[] = [];
|
||||||
filteredTemplates: Template[] = [];
|
filteredTemplates: Template[] = [];
|
||||||
searchText: string = '';
|
searchText: string = '';
|
||||||
@ -47,19 +46,13 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
|||||||
startY: number;
|
startY: number;
|
||||||
|
|
||||||
private subscription: Subscription;
|
private subscription: Subscription;
|
||||||
private themeSubscription: Subscription;
|
|
||||||
private isLightThemeEnabled: boolean = false;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private templateService: TemplateService,
|
private templateService: TemplateService,
|
||||||
private scaleService: MapScaleService,
|
private scaleService: MapScaleService,
|
||||||
private symbolService: SymbolService,
|
private symbolService: SymbolService
|
||||||
private themeService: ThemeService,
|
) {}
|
||||||
private overlayContainer: OverlayContainer,
|
|
||||||
) {
|
|
||||||
this.overlay = overlayContainer.getContainerElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.subscription = this.templateService.newTemplateCreated.subscribe((template: Template) => {
|
this.subscription = this.templateService.newTemplateCreated.subscribe((template: Template) => {
|
||||||
@ -72,23 +65,6 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
|||||||
this.templates = listOfTemplates;
|
this.templates = listOfTemplates;
|
||||||
});
|
});
|
||||||
this.symbolService.list(this.server);
|
this.symbolService.list(this.server);
|
||||||
if (this.themeService.getActualTheme() === 'light') this.isLightThemeEnabled = true;
|
|
||||||
this.themeSubscription = this.themeService.themeChanged.subscribe((value: string) => {
|
|
||||||
if (value === 'light-theme') this.isLightThemeEnabled = true;
|
|
||||||
this.toggleTheme();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleTheme(): void {
|
|
||||||
if (this.overlay.classList.contains("dark-theme")) {
|
|
||||||
this.overlay.classList.remove("dark-theme");
|
|
||||||
this.overlay.classList.add("light-theme");
|
|
||||||
} else if (this.overlay.classList.contains("light-theme")) {
|
|
||||||
this.overlay.classList.remove("light-theme");
|
|
||||||
this.overlay.classList.add("dark-theme");
|
|
||||||
} else {
|
|
||||||
this.overlay.classList.add("light-theme");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sortTemplates() {
|
sortTemplates() {
|
||||||
@ -152,6 +128,19 @@ export class TemplateComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addNewTemplate() {
|
||||||
|
const dialogRef = this.dialog.open(NewTemplateDialogComponent, {
|
||||||
|
width: '1000px',
|
||||||
|
maxHeight: '700px',
|
||||||
|
autoFocus: false,
|
||||||
|
disableClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let instance = dialogRef.componentInstance;
|
||||||
|
instance.server = this.server;
|
||||||
|
instance.project = this.project;
|
||||||
|
}
|
||||||
|
|
||||||
getImageSourceForTemplate(template: Template) {
|
getImageSourceForTemplate(template: Template) {
|
||||||
return `${this.server.protocol}//${this.server.host}:${this.server.port}/v2/symbols/${template.symbol}/raw`;
|
return `${this.server.protocol}//${this.server.host}:${this.server.port}/v2/symbols/${template.symbol}/raw`;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user