Update to primary UI components

This commit is contained in:
Steven 2021-04-07 10:10:17 -04:00
parent 785855d3bd
commit 9da4079d2f
13 changed files with 499 additions and 425 deletions

View File

@ -62,9 +62,9 @@
[drawing]="drawings[0]"
></app-edit-style-action>
<app-edit-text-action
*ngIf="!projectService.isReadOnly(project) &&
(drawings.length===1 && hasTextCapabilities && labels.length===0 && linkNodes.length===0 ||
labels.length===1 && linkNodes.length===0 && drawings.length===0 ||
*ngIf="!projectService.isReadOnly(project) &&
(drawings.length===1 && hasTextCapabilities && labels.length===0 && linkNodes.length===0 ||
labels.length===1 && linkNodes.length===0 && drawings.length===0 ||
linkNodes.length===1 && labels.length===0 && drawings.length===0)"
[server]="server"
[project]="project"
@ -113,13 +113,13 @@
[link]="links[0]"
></app-start-capture-action>
<app-stop-capture-action
*ngIf="!projectService.isReadOnly(project)
*ngIf="!projectService.isReadOnly(project)
&& drawings.length===0 && nodes.length===0 && links.length===1 && linkNodes.length === 0"
[server]="server"
[link]="links[0]"
></app-stop-capture-action>
<app-start-capture-on-started-link-action
*ngIf="!projectService.isReadOnly(project)
*ngIf="!projectService.isReadOnly(project)
&& drawings.length===0 && nodes.length===0 && links.length===1 && linkNodes.length === 0"
[server]="server"
[project]="project"

View File

@ -1,45 +1,43 @@
<button
matTooltip="Console connect to all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="startConsoleForAllNodes()"
class="menu-button"
>
<mat-icon>web_asset</mat-icon>
</button>
<button
matTooltip="Start/Resume all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="startNodes()"
class="menu-button"
>
<mat-icon>play_arrow</mat-icon>
</button>
<button
matTooltip="Suspend all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="suspendNodes()"
class="menu-button"
>
<mat-icon>pause</mat-icon>
</button>
<button
matTooltip="Stop all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="stopNodes()"
class="menu-button"
>
<mat-icon>stop</mat-icon>
</button>
<button
matTooltip="Reload all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="reloadNodes()"
class="menu-button"
>
<mat-icon>replay</mat-icon>
</button>
<div class="menu-button-group">
<button
matTooltip="Console connect to all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="startConsoleForAllNodes()"
class="menu-button">
<mat-icon>web_asset</mat-icon>
</button>
<button
matTooltip="Start/Resume all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="startNodes()"
class="menu-button">
<mat-icon>play_arrow</mat-icon>
</button>
<button
matTooltip="Suspend all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="suspendNodes()"
class="menu-button">
<mat-icon>pause</mat-icon>
</button>
<button
matTooltip="Stop all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="stopNodes()"
class="menu-button">
<mat-icon>stop</mat-icon>
</button>
<button
matTooltip="Reload all nodes"
matTooltipClass="custom-tooltip"
mat-icon-button
(click)="reloadNodes()"
class="menu-button">
<mat-icon>replay</mat-icon>
</button>
</div>

View File

@ -1,14 +1,5 @@
.menu-button {
outline: 0 !important;
transition: 0.5s;
margin-bottom: 16px;
width: 40px;
margin-right: 12px !important;
margin-left: 12px !important;
background: transparent;
padding: 0;
border: none;
background-color: transparent;
margin: 0px 5px !important;
}
.marked {

View File

@ -36,10 +36,11 @@
(click)="addDrawing('ellipse')">
<mat-icon [ngClass]="getCssClassForIcon('ellipse')">panorama_fish_eye</mat-icon>
</button>
<button *ngIf="!isLightThemeEnabled"
matTooltip="Draw a line"
<button
*ngIf="!isLightThemeEnabled"
matTooltip="Draw a line"
matTooltipClass="custom-tooltip"
mat-icon-button class="menu-button"
mat-icon-button class="menu-button"
(click)="addDrawing('line')">
<svg height="40" width="40">
<line
@ -51,10 +52,11 @@
style="stroke:white;stroke-width:2"/>
</svg>
</button>
<button *ngIf="isLightThemeEnabled"
matTooltip="Draw a line"
<button
*ngIf="isLightThemeEnabled"
matTooltip="Draw a line"
matTooltipClass="custom-tooltip"
mat-icon-button class="menu-button"
mat-icon-button class="menu-button"
(click)="addDrawing('line')">
<svg height="40" width="40">
<line

View File

@ -1,24 +1,3 @@
.menu-button {
outline: 0 !important;
transition: 0.5s;
margin-bottom: 16px;
width: 40px;
margin-right: 12px !important;
margin-left: 12px !important;
background: transparent;
padding: 0;
border: none;
background-color: transparent;
}
mat-divider.divider {
height: 40px;
margin-left: 1px;
margin-right: 7px;
width: 10px;
color: gray;
}
.non-visible {
display: none;
}

View File

@ -1,211 +1,177 @@
<div *ngIf="project" class="project-map">
<app-d3-map
*ngIf="!settings.angular_map"
[server]="server"
[project]="project"
[symbols]="symbols"
[nodes]="nodes"
[links]="links"
[drawings]="drawings"
[width]="project.scene_width"
[height]="project.scene_height"
[show-interface-labels]="isInterfaceLabelVisible"
[readonly]="inReadOnlyMode"
(nodeDragged)="onNodeDragged($event)"
(drawingDragged)="onDrawingDragged($event)"
(onLinkCreated)="onLinkCreated($event)"
(onDrawingResized)="onDrawingResized($event)"
></app-d3-map>
<div *ngIf="project" [ngClass]="{lightTheme: isLightThemeEnabled}" class="project-map">
<app-d3-map *ngIf="!settings.angular_map" [server]="server" [project]="project" [symbols]="symbols" [nodes]="nodes" [links]="links" [drawings]="drawings" [width]="project.scene_width" [height]="project.scene_height"
[show-interface-labels]="isInterfaceLabelVisible" [readonly]="inReadOnlyMode" (nodeDragged)="onNodeDragged($event)" (drawingDragged)="onDrawingDragged($event)" (onLinkCreated)="onLinkCreated($event)"
(onDrawingResized)="onDrawingResized($event)">
</app-d3-map>
<app-experimental-map
*ngIf="settings.angular_map"
[symbols]="symbols"
[nodes]="nodes"
[links]="links"
[drawings]="drawings"
[width]="project.scene_width"
[height]="project.scene_height"
[show-interface-labels]="isInterfaceLabelVisible"
[selection-tool]="tools.selection"
[moving-tool]="tools.moving"
[draw-link-tool]="tools.draw_link"
[readonly]="inReadOnlyMode"
></app-experimental-map>
<app-experimental-map *ngIf="settings.angular_map" [symbols]="symbols" [nodes]="nodes" [links]="links" [drawings]="drawings" [width]="project.scene_width" [height]="project.scene_height" [show-interface-labels]="isInterfaceLabelVisible"
[selection-tool]="tools.selection" [moving-tool]="tools.moving" [draw-link-tool]="tools.draw_link" [readonly]="inReadOnlyMode">
</app-experimental-map>
<div *ngIf="toolbarVisibility" class="project-toolbar">
<mat-toolbar color="primary" class="project-toolbar" [ngClass]="{lightTheme: isLightThemeEnabled}">
<mat-toolbar-row *ngIf="!isLightThemeEnabled">
<button matTooltip="Open menu" matTooltipClass="custom-tooltip" mat-icon-button [matMenuTriggerFor]="mainMenu"><mat-icon svgIcon="gns3"></mat-icon></button>
</mat-toolbar-row>
<mat-toolbar-row *ngIf="isLightThemeEnabled">
<button matTooltip="Open menu" matTooltipClass="custom-tooltip" mat-icon-button [matMenuTriggerFor]="mainMenu"><mat-icon svgIcon="gns3black"></mat-icon></button>
</mat-toolbar-row>
<mat-menu #mainMenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item [routerLink]="['/server', server.id, 'projects']">
<mat-icon>work</mat-icon>
<span>Go to projects</span>
</button>
<button mat-menu-item [routerLink]="['/servers']">
<mat-icon>developer_board</mat-icon>
<span>Go to 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 mat-menu-item routerLink="/server/{{server.id}}/systemstatus">
<mat-icon>info</mat-icon>
<span>Go to system status</span>
</button>
<button mat-menu-item routerLink="/settings">
<mat-icon>settings</mat-icon>
<span>Go to settings</span>
</button>
<button mat-menu-item (click)="addNewTemplate()">
<mat-icon>control_point</mat-icon>
<span>New template</span>
</button>
<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 #projectMenu="matMenu" [overlapTrigger]="false">
<div>
<button mat-menu-item (click)="addNewProject()">
<mat-icon>add</mat-icon>
<span>Add new blank project</span>
</button>
<button mat-menu-item (click)="saveProject()">
<mat-icon>save</mat-icon>
<span>Save project as</span>
</button>
<button mat-menu-item (click)="editProject()">
<mat-icon>edit</mat-icon>
<span>Edit project</span>
</button>
<button mat-menu-item (click)="exportProject()">
<mat-icon>call_made</mat-icon>
<span>Export portable project</span>
</button>
<button mat-menu-item (click)="importProject()">
<mat-icon>call_received</mat-icon>
<span>Import portable project</span>
</button>
<button mat-menu-item (click)="closeProject()">
<mat-icon>close</mat-icon>
<span>Close project</span>
</button>
<button mat-menu-item (click)="deleteProject()">
<mat-icon>delete</mat-icon>
<span>Delete project</span>
</button>
</div>
</mat-menu>
<mat-menu #viewMenu="matMenu" [overlapTrigger]="false">
<div class="options-item">
<mat-checkbox [ngModel]="isInterfaceLabelVisible" (change)="toggleShowInterfaceLabels($event.checked)">
Show interface labels
</mat-checkbox><br/>
<mat-checkbox [ngModel]="isConsoleVisible" (change)="toggleShowConsole($event.checked)">
Show console
</mat-checkbox><br/>
<mat-checkbox [ngModel]="isTopologySummaryVisible" (change)="toggleShowTopologySummary($event.checked)">
Show topology/servers summary
</mat-checkbox><br/>
<mat-checkbox [ngModel]="notificationsVisibility" (change)="toggleNotifications($event.checked)">
Show notifications
</mat-checkbox><br/>
<mat-checkbox [ngModel]="layersVisibility" (change)="toggleLayers($event.checked)">
Show layers
</mat-checkbox><br/>
<mat-checkbox [ngModel]="gridVisibility" (change)="toggleGrid($event.checked)">
Show grid
</mat-checkbox><br/>
<mat-checkbox [ngModel]="project.snap_to_grid" (change)="toggleSnapToGrid($event.checked)">
Snap to grid
</mat-checkbox><br/>
</div>
</mat-menu>
<mat-toolbar-row *ngIf="!readonly">
<app-template [server]="server" [project]="project" (onNodeCreation)="onNodeCreation($event)"></app-template>
</mat-toolbar-row>
<mat-toolbar-row *ngIf="!readonly">
<button matTooltip="Add a link" matTooltipClass="custom-tooltip" mat-icon-button [color]="tools.draw_link ? 'primary' : 'basic'" (click)="toggleDrawLineMode()">
<!-- Project Titlebar -->
<div id="project-titlebar" [ngClass]="{lightTheme: isLightThemeEnabled}">
<button matTooltip="Open menu" matTooltipClass="custom-tooltip" mat-icon-button class="gns3-button menu-button" [matMenuTriggerFor]="mainMenu">
<mat-icon svgIcon="gns3"></mat-icon>
</button>
<div class="project-titlebar-controls">
<div *ngIf="!readonly" class="menu-button-group primary-controls">
<app-template [server]="server" [project]="project" (onNodeCreation)="onNodeCreation($event)">
</app-template>
<button matTooltip="Add a link" matTooltipClass="custom-tooltip" class="menu-button" mat-icon-button [ngClass]="{selected: tools.draw_link}" [color]="tools.draw_link ? 'primary' : 'basic'" (click)="toggleDrawLineMode()">
<mat-icon>timeline</mat-icon>
</button>
</mat-toolbar-row>
</div>
<div class="menu-button-group">
<app-nodes-menu [server]="server" [project]="project"></app-nodes-menu>
<app-context-menu [project]="project" [server]="server"></app-context-menu>
<app-context-console-menu [project]="project" [server]="server"></app-context-console-menu>
</div>
</div>
<div>
<button matTooltip="Toggle topology/servers summary" matTooltipClass="custom-tooltip" mat-icon-button [color]="isTopologySummaryVisible ? 'primary' : 'basic'" (click)="toggleShowTopologySummary(!isTopologySummaryVisible)">
<mat-icon>toc</mat-icon>
</button>
</div>
<mat-toolbar-row>
<button matTooltip="Enable/disable moving mode" matTooltipClass="custom-tooltip" mat-icon-button [color]="tools.moving ? 'primary' : 'basic'" (click)="toggleMovingMode()">
<mat-icon>zoom_out_map</mat-icon>
<!-- GNS3 menu -->
<mat-menu #mainMenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item [routerLink]="['/server', server.id, 'projects']">
<mat-icon>work</mat-icon>
<span>Go to projects</span>
</button>
<button mat-menu-item [routerLink]="['/servers']">
<mat-icon>developer_board</mat-icon>
<span>Go to 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 mat-menu-item routerLink="/server/{{server.id}}/systemstatus">
<mat-icon>info</mat-icon>
<span>Go to system status</span>
</button>
<button mat-menu-item routerLink="/settings">
<mat-icon>settings</mat-icon>
<span>Go to settings</span>
</button>
<button mat-menu-item (click)="addNewTemplate()">
<mat-icon>control_point</mat-icon>
<span>New template</span>
</button>
<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>
<!-- Project Settings sub-menu -->
<mat-menu #projectMenu="matMenu" [overlapTrigger]="false">
<div>
<button mat-menu-item (click)="addNewProject()">
<mat-icon>add</mat-icon>
<span>Add new blank project</span>
</button>
</mat-toolbar-row>
<mat-toolbar-row *ngIf="!readonly">
<app-snapshot-menu-item [server]="server" [project]="project"> </app-snapshot-menu-item>
</mat-toolbar-row>
<mat-toolbar-row *ngIf="!readonly">
<button matTooltip="Fit in view" matTooltipClass="custom-tooltip" mat-icon-button (click)="fitInView()">
<mat-icon>fullscreen</mat-icon>
<button mat-menu-item (click)="saveProject()">
<mat-icon>save</mat-icon>
<span>Save project as</span>
</button>
</mat-toolbar-row>
<mat-toolbar-row *ngIf="!readonly">
<button matTooltip="Center view" matTooltipClass="custom-tooltip" mat-icon-button (click)="centerView()">
<mat-icon>center_focus_strong</mat-icon>
<button mat-menu-item (click)="editProject()">
<mat-icon>edit</mat-icon>
<span>Edit project</span>
</button>
</mat-toolbar-row>
</mat-toolbar>
<button mat-menu-item (click)="exportProject()">
<mat-icon>call_made</mat-icon>
<span>Export portable project</span>
</button>
<button mat-menu-item (click)="importProject()">
<mat-icon>call_received</mat-icon>
<span>Import portable project</span>
</button>
<button mat-menu-item (click)="closeProject()">
<mat-icon>close</mat-icon>
<span>Close project</span>
</button>
<button mat-menu-item (click)="deleteProject()">
<mat-icon>delete</mat-icon>
<span>Delete project</span>
</button>
</div>
</mat-menu>
<!-- Map Settings sub-menu -->
<mat-menu #viewMenu="matMenu" [overlapTrigger]="false">
<div class="options-item">
<mat-checkbox [ngModel]="isInterfaceLabelVisible" (change)="toggleShowInterfaceLabels($event.checked)">
Show interface labels
</mat-checkbox><br />
<mat-checkbox [ngModel]="isConsoleVisible" (change)="toggleShowConsole($event.checked)">
Show console
</mat-checkbox><br />
<mat-checkbox [ngModel]="isTopologySummaryVisible" (change)="toggleShowTopologySummary($event.checked)">
Show topology/servers summary
</mat-checkbox><br />
<mat-checkbox [ngModel]="notificationsVisibility" (change)="toggleNotifications($event.checked)">
Show notifications
</mat-checkbox><br />
<mat-checkbox [ngModel]="layersVisibility" (change)="toggleLayers($event.checked)">
Show layers
</mat-checkbox><br />
<mat-checkbox [ngModel]="gridVisibility" (change)="toggleGrid($event.checked)">
Show grid
</mat-checkbox><br />
<mat-checkbox [ngModel]="project.snap_to_grid" (change)="toggleSnapToGrid($event.checked)">
Snap to grid
</mat-checkbox><br />
</div>
</mat-menu>
</div>
<div *ngIf="toolbarVisibility" id="show-menu-wrapper" [ngClass]="{lightTheme: isLightThemeEnabled, shadowed: !isProjectMapMenuVisible }">
<button [ngClass]="{lightTheme: isLightThemeEnabled, darkTheme: !isLightThemeEnabled}" class="arrow-button" mat-icon-button (click)="showMenu()"><mat-icon class="unmarked">keyboard_arrow_right</mat-icon></button>
<!-- Project toolbar -->
<div id="project-toolbar" [ngClass]="{lightTheme: isLightThemeEnabled}">
<div class="section">
<button matTooltip="Selection mode" matTooltipClass="custom-tooltip" mat-icon-button class="selection-button menu-button" [color]="tools.moving ? 'basic' : 'primary'" (click)="toggleMovingMode()">
<mat-icon>near_me</mat-icon>
</button>
<button matTooltip="Pan workspace" matTooltipClass="custom-tooltip" class="pan-button menu-button" mat-icon-button [color]="tools.moving ? 'primary' : 'basic'" (click)="toggleMovingMode()">
<mat-icon>zoom_out_map</mat-icon>
</button>
<button matTooltip="Zoom in" matTooltipClass="custom-tooltip" [ngClass]="{lightTheme: isLightThemeEnabled}" class="menu-button" (click)="zoomIn()">
<mat-icon>zoom_in</mat-icon>
</button>
<button matTooltip="Reset zoom" matTooltipClass="custom-tooltip" [ngClass]="{lightTheme: isLightThemeEnabled}" class="menu-button" (click)="resetZoom()">
<mat-icon>adjust</mat-icon>
</button>
<button matTooltip="Zoom out" matTooltipClass="custom-tooltip" [ngClass]="{lightTheme: isLightThemeEnabled}" class="menu-button" (click)="zoomOut()">
<mat-icon>zoom_out</mat-icon>
</button>
</div>
<div class="section">
<app-project-map-menu [server]="server" [project]="project"></app-project-map-menu>
</div>
<div *ngIf="!readonly" class="section">
<app-snapshot-menu-item [server]="server" [project]="project"> </app-snapshot-menu-item>
</div>
</div>
<div *ngIf="toolbarVisibility" id="menu-wrapper" [ngClass]="{lightTheme: isLightThemeEnabled, extended: isProjectMapMenuVisible }">
<app-nodes-menu [server]="server" [project]="project"></app-nodes-menu>
<mat-divider class="divider" [vertical]="true"></mat-divider>
<app-project-map-menu [server]="server" [project]="project"></app-project-map-menu>
<button [ngClass]="{lightTheme: isLightThemeEnabled}" class="arrow-button" mat-icon-button (click)="hideMenu()"><mat-icon class="unmarked">keyboard_arrow_left</mat-icon></button>
<app-progress></app-progress>
<app-draw-link-tool [links]="links" *ngIf="tools.draw_link"></app-draw-link-tool>
<app-drawing-dragged [server]="server" [project]="project"></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" [project]="project"></app-node-dragged>
<app-node-label-dragged [server]="server"></app-node-label-dragged>
<app-text-added [server]="server" [project]="project" (drawingSaved)="onDrawingSaved()"> </app-text-added>
<app-text-edited [server]="server"></app-text-edited>
<div [ngClass]="{ visible: !isConsoleVisible }">
<app-console-wrapper *ngIf="project" [server]="server" [project]="project" (closeConsole)='toggleShowConsole($event)'></app-console-wrapper>
</div>
<div [ngClass]="{ visible: !isTopologySummaryVisible }">
<app-topology-summary *ngIf="project" [server]="server" [project]="project" (closeTopologySummary)='toggleShowTopologySummary($event)'></app-topology-summary>
</div>
<app-context-menu [project]="project" [server]="server"></app-context-menu>
<app-context-console-menu [project]="project" [server]="server"></app-context-console-menu>
</div>
<div [ngClass]="{lightTheme: isLightThemeEnabled}" class="zoom-buttons">
<button matTooltip="Zoom in" matTooltipClass="custom-tooltip" [ngClass]="{lightTheme: isLightThemeEnabled}" class="zoom-button" (click)="zoomIn()"><mat-icon>zoom_in</mat-icon></button>
<button matTooltip="Reset zoom" matTooltipClass="custom-tooltip" [ngClass]="{lightTheme: isLightThemeEnabled}" class="zoom-button" (click)="resetZoom()"><mat-icon>adjust</mat-icon></button>
<button matTooltip="Zoom out" matTooltipClass="custom-tooltip" [ngClass]="{lightTheme: isLightThemeEnabled}" class="zoom-button" (click)="zoomOut()"><mat-icon>zoom_out</mat-icon></button>
</div>
<app-progress></app-progress>
<app-draw-link-tool [links]="links" *ngIf="tools.draw_link"></app-draw-link-tool>
<app-drawing-dragged [server]="server" [project]="project"></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" [project]="project"></app-node-dragged>
<app-node-label-dragged [server]="server"></app-node-label-dragged>
<app-text-added [server]="server" [project]="project" (drawingSaved)="onDrawingSaved()"> </app-text-added>
<app-text-edited [server]="server"></app-text-edited>
<div [ngClass]="{ visible: !isConsoleVisible }">
<app-console-wrapper *ngIf="project" [server]="server" [project]="project" (closeConsole)='toggleShowConsole($event)'></app-console-wrapper>
</div>
<div [ngClass]="{ visible: !isTopologySummaryVisible }">
<app-topology-summary *ngIf="project" [server]="server" [project]="project" (closeTopologySummary)='toggleShowTopologySummary($event)'></app-topology-summary>
</div>

View File

@ -9,20 +9,154 @@ app-map {
width: auto;
}
svg.map {
background-color: #f0f0f0;
}
g.node:hover {
background-color: #0097a7;
}
.project-toolbar {
width: 70px;
position: fixed;
top: 20px;
left: 20px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
.project-map {
background-color: #e8ecef;
}
#project-titlebar {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
height: 60px;
padding: 0px 20px;
background-color: #20313b;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 3px 3px 10px rgba(0,0,0,0.2);
z-index: 2;
.gns3-button {
position: relative;
top: -2px;
mat-icon {
width: 30px !important;
height: 30px !important;
}
}
.primary-controls {
border-right: 1px solid rgba(255,255,255,0.3);
padding-right: 15px;
margin-right: 15px;
}
.menu-button-group {
display: flex;
align-items: center;
height: 24px;
}
.menu-button {
display: flex;
justify-content: center;
align-items: center;
height: 36px;
width: 36px;
margin: 0px 8px;
border-radius: 18px;
background: none;
font-size: 20px;
}
.add-menu-button mat-icon {
font-size: 28px !important;
}
.selected {
background: rgba(0, 151, 167, 0.1);
mat-icon {
color: #0097a7 !important;
}
}
.project-titlebar-controls {
display: flex;
align-items: center;
}
&.lightTheme {
background-color: #20313b !important;
mat-icon {
color: #fff !important;
}
.selected mat-icon {
color: #0097a7 !important;
}
}
}
#project-toolbar {
position: fixed;
top: 60px;
left: 0px;
width: 50px;
margin: 20px;
background-color: rgba(15,18,20,0.90);
border-radius: 6px;
box-shadow: 1px 1px 10px rgba(0,0,0,0.2);
z-index: 2;
mat-icon {
font-size: 20px;
}
.menu-button {
display: flex;
justify-content: center;
align-items: center;
height: 36px;
width: 36px;
border-radius: 18px;
background: none;
margin: 2px 0px;
}
.selection-button {
margin-bottom: 0px !important;
}
.snapshot-button mat-icon {
font-size: 16px;
}
.section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-top: 1px solid rgba(255,255,255,0.3);
padding: 5px 0px;
&:first-child {
border: none;
}
}
&.lightTheme {
background-color: rgba(244, 248, 252, 0.95) !important;
.menu-button {
opacity: 0.7;
}
.section {
border-top: 1px solid rgba(0,0,0,0.1);
&:first-child {
border: none;
}
}
}
}
img {
@ -31,7 +165,6 @@ img {
}
.lightTheme {
background: white!important;
color: black!important;
}
@ -42,7 +175,7 @@ img {
#show-menu-wrapper {
position: fixed;
background: transparent;
top: 20px;
top: 0px;
left: 92px;
background: #263238;
height: 72px;
@ -64,8 +197,9 @@ img {
#menu-wrapper {
position: fixed;
background: transparent;
top: 20px;
top: 0px;
left: 92px;
right: 0px;
background: #263238;
height: 72px;
padding-top: 16px;
@ -111,30 +245,6 @@ mat-divider.divider {
color: gray;
}
.zoom-buttons {
position: fixed;
background: #263238;
bottom: 20px;
right: 20px;
display: grid;
color: white;
.zoom-button {
outline: none;
height: 40px;
width: 40px;
background: transparent;
border: none;
color: white;
font-size: 1.25rem;
font-weight: bold;
mat-icon {
margin-left: -6px;
}
}
}
@-moz-document url-prefix() {
/** fixes gray background of drawing menu on Firefox **/
.mat-drawer-content {

View File

@ -1 +1,8 @@
<button matTooltip="Manage snapshots" matTooltipClass="custom-tooltip" mat-icon-button (click)="createSnapshotModal()"><mat-icon>snooze</mat-icon></button>
<button
matTooltip="Manage snapshots"
matTooltipClass="custom-tooltip"
mat-icon-button
class="snapshot-button menu-button"
(click)="createSnapshotModal()">
<mat-icon>filter_none</mat-icon>
</button>

View File

@ -1,15 +1,24 @@
<button class="addNode" matTooltip="Add a node" matTooltipClass="custom-tooltip" mat-icon-button [matMenuTriggerFor]="mainMenu">
<mat-icon>add_to_queue</mat-icon>
<button
class="addNode"
matTooltip="Add a node"
matTooltipClass="custom-tooltip"
mat-icon-button
class="menu-button add-menu-button"
[matMenuTriggerFor]="mainMenu">
<mat-icon>add</mat-icon>
</button>
<mat-menu #mainMenu="matMenu">
<button mat-menu-item (click)="openDialog()">
<mat-icon>add</mat-icon>
<mat-icon>add_to_queue</mat-icon>
<span>Open dialog to configure</span>
</button>
<mat-form-field (click)="$event.stopPropagation()" class="form-field" floatPlaceholder="never">
<input
<mat-form-field
(click)="$event.stopPropagation()"
class="form-field"
floatPlaceholder="never">
<input
matInput
placeholder="Search by name"
(keyup)="filterTemplates($event)"
@ -17,8 +26,8 @@
[ngModelOptions]="{standalone: true}">
</mat-form-field>
<mat-form-field (click)="$event.stopPropagation()" class="form-field">
<mat-select
[ngModelOptions]="{standalone: true}"
<mat-select
[ngModelOptions]="{standalone: true}"
placeholder="Filter templates by type"
(selectionChange)="filterTemplates($event)"
[(ngModel)]="selectedType">

View File

@ -4,10 +4,10 @@
(document:mouseup)="toggleDragging(false)">
</div>
<div
class="summaryWrapper"
class="summaryWrapper"
(mousedown)="toggleDragging(true)"
*ngIf="projectsStatistics"
[ngStyle]="style"
*ngIf="projectsStatistics"
[ngStyle]="style"
[ngClass]="{lightTheme: isLightThemeEnabled}"
mwlResizable
[validateResize]="validate"
@ -16,77 +16,82 @@
(resizeStart)="toggleDragging(false)"
(resizeEnd)="onResizeEnd($event)">
<div class="summaryHeader">
<button class="titleButton" [ngClass]="{ marked: isTopologyVisible }" (click)="toogleTopologyVisibility(true)" mat-button>Map topology</button>
<button class="titleButton" [ngClass]="{ marked: !isTopologyVisible }" (click)=toogleTopologyVisibility(false) mat-button>Servers</button>
<mat-icon (click)="close()" class="closeButton">close</mat-icon>
</div>
<div [ngClass]="{ notvisible: !isTopologyVisible }">
<mat-divider class="divider"></mat-divider>
<div class="summaryFilters">
<mat-select placeholder="Filter nodes" multiple>
<mat-optgroup label="Status filter">
<mat-option value="started" (onSelectionChange)="applyStatusFilter('started')">started</mat-option>
<mat-option value="suspended" (onSelectionChange)="applyStatusFilter('suspended')">suspended</mat-option>
<mat-option value="stopped" (onSelectionChange)="applyStatusFilter('stopped')">stopped</mat-option>
</mat-optgroup>
<mat-optgroup label="Capture filter">
<mat-option value="capture" (onSelectionChange)="applyCaptureFilter('capture')">active capture(s)</mat-option>
<mat-option value="packet" (onSelectionChange)="applyCaptureFilter('packet')">active packet captures</mat-option>
</mat-optgroup>
</mat-select>
</div>
<div class="summarySorting">
<mat-select (selectionChange)="setSortingOrder()" placeholder="Sorting" [(value)]="sortingOrder">
<mat-option value="asc">sort by name ascending</mat-option>
<mat-option value="desc">sort by name descending</mat-option>
</mat-select>
</div>
<mat-divider class="divider"></mat-divider>
<div
[ngStyle]="styleInside"
class="summaryContent">
<div class="nodeRow" *ngFor="let node of filteredNodes">
<div>
<svg *ngIf="node.status==='started'" width="10" height="10">
<rect class="status_started" x="0" y="0" width="10" height="10" fill="green"></rect>
</svg>
<svg *ngIf="node.status==='suspended'" width="10" height="10">
<rect class="status_suspended" x="0" y="0" width="10" height="10" fill="yellow"></rect>
</svg>
<svg *ngIf="node.status==='stopped'" width="10" height="10">
<rect class="status_stopped" x="0" y="0" width="10" height="10" fill="red"></rect>
</svg>
{{node.name}}
</div>
<div *ngIf="node.console!=null && node.console!=undefined && node.console_type!='none'">
{{node.console_type}} {{node.console_host}}:{{node.console}}
</div>
<div *ngIf="node.console===null || node.console===undefined || node.console_type==='none'">
none
</div>
</div>
</div>
</div>
<div [ngClass]="{ notvisible: isTopologyVisible }">
<mat-divider class="divider"></mat-divider>
<div class="summaryContentServers">
<div class="nodeRow" *ngFor="let compute of computes">
<div>
<svg *ngIf="compute.connected" width="10" height="10">
<rect class="status_started" x="0" y="0" width="10" height="10" fill="green"></rect>
</svg>
<svg *ngIf="!compute.connected" width="10" height="10">
<rect class="status_stopped" x="0" y="0" width="10" height="10" fill="red"></rect>
</svg>
{{compute.name}}
</div>
<div>
{{compute.host}}
</div>
<div>
{{server.location}}
</div>
</div>
</div>
<mat-tab-group>
<mat-tab
(click)="toggleTopologyVisibility(true)"
label="Map topology">
<div class="tabContent">
<div class="summaryFilters">
<mat-select placeholder="Filter nodes" multiple>
<mat-optgroup label="Status filter">
<mat-option value="started" (onSelectionChange)="applyStatusFilter('started')">started</mat-option>
<mat-option value="suspended" (onSelectionChange)="applyStatusFilter('suspended')">suspended</mat-option>
<mat-option value="stopped" (onSelectionChange)="applyStatusFilter('stopped')">stopped</mat-option>
</mat-optgroup>
<mat-optgroup label="Capture filter">
<mat-option value="capture" (onSelectionChange)="applyCaptureFilter('capture')">active capture(s)</mat-option>
<mat-option value="packet" (onSelectionChange)="applyCaptureFilter('packet')">active packet captures</mat-option>
</mat-optgroup>
</mat-select>
</div>
<div class="summarySorting">
<mat-select (selectionChange)="setSortingOrder()" placeholder="Sorting" [(value)]="sortingOrder">
<mat-option value="asc">sort by name ascending</mat-option>
<mat-option value="desc">sort by name descending</mat-option>
</mat-select>
</div>
<mat-divider class="divider"></mat-divider>
<div
[ngStyle]="styleInside"
class="summaryContent">
<div class="nodeRow" *ngFor="let node of filteredNodes">
<div>
<svg *ngIf="node.status==='started'" width="10" height="10">
<rect class="status_started" x="0" y="0" width="10" height="10" fill="green"></rect>
</svg>
<svg *ngIf="node.status==='suspended'" width="10" height="10">
<rect class="status_suspended" x="0" y="0" width="10" height="10" fill="yellow"></rect>
</svg>
<svg *ngIf="node.status==='stopped'" width="10" height="10">
<rect class="status_stopped" x="0" y="0" width="10" height="10" fill="red"></rect>
</svg>
{{node.name}}
</div>
<div *ngIf="node.console!=null && node.console!=undefined && node.console_type!='none'">
{{node.console_type}} {{node.console_host}}:{{node.console}}
</div>
<div *ngIf="node.console===null || node.console===undefined || node.console_type==='none'">
none
</div>
</div>
</div>
</div>
</mat-tab>
<mat-tab
(click)="toggleTopologyVisibility(false)"
label="Servers">
<div class="tabContent">
<div class="summaryContentServers">
<div class="nodeRow" *ngFor="let compute of computes">
<div>
<svg *ngIf="compute.connected" width="10" height="10">
<rect class="status_started" x="0" y="0" width="10" height="10" fill="green"></rect>
</svg>
<svg *ngIf="!compute.connected" width="10" height="10">
<rect class="status_stopped" x="0" y="0" width="10" height="10" fill="red"></rect>
</svg>
{{compute.name}}
</div>
<div>
{{compute.host}}
</div>
<div>
{{server.location}}
</div>
</div>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
</div>

View File

@ -7,19 +7,23 @@
.summaryWrapper {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
position: fixed;
top: 20px;
right: 20px;
top: 60px;
right: 0px;
height: 400px;
width: 300px;
width: 320px;
background: #263238;
color: white;
overflow: hidden;
font-size: 12px;
margin: 20px;
border-radius: 8px;
}
.lightTheme {
background: white!important;
background-color: rgba(244, 248, 252, 0.95);
color: black;
margin: 20px;
border-radius: 8px;
}
.summaryHeaderMenu {
@ -28,10 +32,7 @@
.summaryHeader {
width: 100%;
height: 34px;
display: flex;
justify-content: space-between;
margin-right: 5px;
}
.summaryFilters {
@ -46,17 +47,17 @@
margin-right: 5px;
}
.tabContent {
padding: 10px;
}
.summaryContent {
margin-left: 5px;
margin-right: 5px;
overflow: auto;
scrollbar-color: darkgrey #263238;
scrollbar-width: thin;
}
.summaryContentServers {
margin-left: 5px;
margin-right: 5px;
max-height: 350px;
overflow: auto;
scrollbar-color: darkgrey #263238;
@ -67,10 +68,12 @@
margin-left: 5px;
margin-top: 4px;
outline: none;
border-radius: 0px;
}
.marked {
color: #0097a7;
border-bottom: 2px solid #0097a7;
}
.divider {

View File

@ -38,7 +38,7 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
captureFilterEnabled: boolean = false;
packetFilterEnabled: boolean = false;
computes: Compute[] = [];
isTopologyVisible: boolean = true;
isDraggingEnabled: boolean = false;
isLightThemeEnabled: boolean = false;
@ -52,7 +52,7 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
) {}
ngOnInit() {
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
this.subscriptions.push(
this.nodesDataSource.changes.subscribe((nodes: Node[]) => {
this.nodes = nodes;
@ -77,7 +77,7 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
this.computes = computes;
});
this.style = { top: '20px', right: '20px', width: '300px', height: '400px'};
this.style = { top: '60px', right: '0px', width: '320px', height: '400px'};
}
toggleDragging(value: boolean) {
@ -138,7 +138,7 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
};
}
toogleTopologyVisibility(value: boolean) {
toggleTopologyVisibility(value: boolean) {
this.isTopologyVisible = value;
}
@ -161,7 +161,7 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
this.filteredNodes = this.filteredNodes.sort(this.compareAsc);
} else {
this.filteredNodes = this.filteredNodes.sort(this.compareDesc);
}
}
}
applyStatusFilter(filter: string) {
@ -190,15 +190,15 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
if (this.startedStatusFilterEnabled) {
nodes = nodes.concat(this.nodes.filter(n => n.status === 'started'));
}
if (this.stoppedStatusFilterEnabled) {
nodes = nodes.concat(this.nodes.filter(n => n.status === 'stopped'));
}
if (this.suspendedStatusFilterEnabled) {
nodes = nodes.concat(this.nodes.filter(n => n.status === 'suspended'));
}
if (!this.startedStatusFilterEnabled && !this.stoppedStatusFilterEnabled && !this.suspendedStatusFilterEnabled) {
nodes = nodes.concat(this.nodes);
}
@ -215,7 +215,7 @@ export class TopologySummaryComponent implements OnInit, OnDestroy {
this.filteredNodes = nodes.sort(this.compareAsc);
} else {
this.filteredNodes = nodes.sort(this.compareDesc);
}
}
}
checkCapturing(nodes: Node[]): Node[] {

View File

@ -1,3 +1,7 @@
body {
background-color: #e8ecef;
}
img.logo-header {
width: 50px;
}