mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-12 12:48:51 +00:00
initial commit of chrome only of new replacement web ui
remove node modules make new data file for web ui initial commit of dashboard switch back to non SSL request move port splitting to common place; add to node resource location Signed-off-by: Patrick Reilly <patrick@kismatic.io> various path fixes make svg path relative work around missing mime type Signed-off-by: Patrick Reilly <patrick@kismatic.io> fix paths fix karma path remove bad protractor test
This commit is contained in:
125
www/app/components/README.md
Normal file
125
www/app/components/README.md
Normal file
@@ -0,0 +1,125 @@
|
||||
Components
|
||||
==========
|
||||
|
||||
A tab in the Kubernetes UI with its set of visualizations is referred to as a *component*. Components are separated from the UI chrome and base data providers to simplify the development of new visualizations. This document provides reference for creation and modification of components.
|
||||
|
||||
Each component has its own directory, which contains a manifest file, HTML views, Angular providers, CSS, Less and other assets. Below is the recommended directory structure for a component.
|
||||
```
|
||||
foo_component
|
||||
├── config
|
||||
├── css
|
||||
├── img
|
||||
├── js
|
||||
│ └── modules
|
||||
│ ├── controllers
|
||||
│ ├── directives
|
||||
│ └── services
|
||||
├── less
|
||||
├── pages
|
||||
├── views
|
||||
│ └── partials
|
||||
└── manifest.json
|
||||
```
|
||||
|
||||
###Manifest file
|
||||
|
||||
The JSON-formatted manifest file, named ```manifest.json```, is located at the root of a component. Based on the component directory name and the contents of the manifest, the Kubernetes UI automatically adds a tab to the chrome, a dependency on the component's AngularJS module to main AngularJS app and Angular routes for the component.
|
||||
|
||||
For example, consider a manifest file at ```master/components/foo_component/manifest.json```:
|
||||
```
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"url": "/",
|
||||
"templateUrl": "/components/foo_component/pages/home.html"
|
||||
},
|
||||
{
|
||||
"url": "/kittens",
|
||||
"templateUrl": "/components/foo_component/pages/kittens.html",
|
||||
"css": "/components/foo_component/css/kittens.css"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
From the name of the component directory, the Kubernetes UI
|
||||
* creates a tab called "Foo Component",
|
||||
* adds Angular module ```kubernetesApp.components.fooComponent``` to the dependencies of ```kubernetesApp```, and
|
||||
* defines Angular routes ```/foo_component/``` and ```/foo_component/kittens```.
|
||||
|
||||
Every tab links to ```/``` relative to its component, so it is important to always define a ```/``` route.
|
||||
|
||||
###Source files
|
||||
In general, all files located in ```master/components/<component>``` are copied to ```app/components/<component>/``` on each gulp build. This includes (but is not limited to) HTML views, CSS and images. Exceptions to this copy are the ```config``` and ```less``` directories as well as all ```.js``` files.
|
||||
|
||||
The sections below describe how the exceptions are built into the UI.
|
||||
|
||||
####JavaScript
|
||||
All JavaScript files located in the ```master/components/<component>/js``` are uglified and concatenated together with the rest of the UI's JavaScript. Once aggregated, the JavaScript file is minified and written to ```app/assets/js/app.js```.
|
||||
|
||||
####Configuration
|
||||
|
||||
Similar to the [UI-wide configuration](../../README.md#configuration), components can define different configuration for each environment. The gulp task creates the constant ```ENV``` under the ```kubernetesApp.config``` module for configuration, which is an object with a property for the root UI and each component.
|
||||
|
||||
For example, a configuration for the ```development``` environment specific to ```foo_component``` would be located at ```master/components/foo_component/config/development.json```. Such a component would access its ```development.json``` configuration verbatim at ```ENV.foo_component```:
|
||||
```
|
||||
angular.module('kubernetesApp.components.fooComponent', ['kubernetesApp.config'])
|
||||
.provider('foo', ...)
|
||||
.config(['fooProvider', 'ENV', function(fooProvider, ENV) {
|
||||
// Configure fooProvider using ENV['foo_component'].
|
||||
});
|
||||
```
|
||||
|
||||
####Less
|
||||
|
||||
Like JavaScript, the component's Less files are built into one monolithic CSS file. All top-level Less files located at ```master/components/<component>/less/*.less``` are imported into the main UI's Less file. The result is then minified and copied to ```app/assets/css/app.css```.
|
||||
|
||||
Sub-directories of this path are watched for changes, but not directly imported. This is useful for defining common colors, mixins and other functions or variables used by the top-level Less files.
|
||||
|
||||
###Appendix
|
||||
|
||||
####Manifest schema
|
||||
|
||||
```
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Very brief summary of the component. Use a README.md file for detailed descriptions."
|
||||
},
|
||||
"routes": {
|
||||
"type": "array",
|
||||
"description": "Angular routes for the component.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Short description of the route."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Route location relative to '/<component>'."
|
||||
},
|
||||
"templateUrl": {
|
||||
"type": "string",
|
||||
"description": "Absolute location of the HTML template."
|
||||
},
|
||||
"css": {
|
||||
"type": "string",
|
||||
"description": "Absolute location of CSS to use with this route."
|
||||
}
|
||||
},
|
||||
"required": ["url", "templateUrl"]
|
||||
},
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["routes"]
|
||||
}
|
||||
```
|
||||
|
||||
Content available under the [CC-By 3.0
|
||||
license](http://creativecommons.org/licenses/by/3.0/)
|
1
www/app/components/dashboard/README.md
Normal file
1
www/app/components/dashboard/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Dashboard Component for Kubernetes WebUI
|
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><path d="M5 8l4 4 4-4z"/></svg>
|
After Width: | Height: | Size: 114 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M7 10l5 5 5-5z"/>
|
||||
<path d="M0 0h24v24h-24z" fill="none"/>
|
||||
</svg>
|
After Width: | Height: | Size: 166 B |
1
www/app/components/dashboard/img/icons/ic_close_18px.svg
Normal file
1
www/app/components/dashboard/img/icons/ic_close_18px.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><path d="M14.53 4.53l-1.06-1.06L9 7.94 4.53 3.47 3.47 4.53 7.94 9l-4.47 4.47 1.06 1.06L9 10.06l4.47 4.47 1.06-1.06L10.06 9z"/></svg>
|
After Width: | Height: | Size: 215 B |
1
www/app/components/dashboard/img/icons/ic_close_24px.svg
Normal file
1
www/app/components/dashboard/img/icons/ic_close_24px.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
After Width: | Height: | Size: 202 B |
60
www/app/components/dashboard/manifest.json
Normal file
60
www/app/components/dashboard/manifest.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"description": "The basic kubernetes ui dashboard... ",
|
||||
"routes": [
|
||||
{
|
||||
"description": "Dashboard visualization.",
|
||||
"url": "/",
|
||||
"templateUrl": "components/dashboard/pages/home.html"
|
||||
},
|
||||
{
|
||||
"description": "Pods",
|
||||
"url": "/pods",
|
||||
"templateUrl": "components/dashboard/views/listPods.html"
|
||||
},
|
||||
{
|
||||
"description": "Pod Visualizer",
|
||||
"url": "/visualpods",
|
||||
"templateUrl": "components/dashboard/views/listPodsVisualizer.html"
|
||||
},
|
||||
{
|
||||
"description": "Services",
|
||||
"url": "/services",
|
||||
"templateUrl": "components/dashboard/views/listServices.html"
|
||||
},
|
||||
{
|
||||
"description": "Replication Controllers",
|
||||
"url": "/replicationcontrollers",
|
||||
"templateUrl": "components/dashboard/views/listReplicationControllers.html"
|
||||
},
|
||||
{
|
||||
"description": "Events",
|
||||
"url": "/events",
|
||||
"templateUrl": "components/dashboard/views/listEvents.html"
|
||||
},
|
||||
{
|
||||
"description": "Minions",
|
||||
"url": "/minions",
|
||||
"templateUrl": "components/dashboard/views/listMinions.html"
|
||||
},
|
||||
{
|
||||
"description": "Replication Controller",
|
||||
"url": "/replicationcontrollers/:replicationControllerId",
|
||||
"templateUrl": "components/dashboard/views/replication.html"
|
||||
},
|
||||
{
|
||||
"description": "Service",
|
||||
"url": "/services/:serviceId",
|
||||
"templateUrl": "components/dashboard/views/service.html"
|
||||
},
|
||||
{
|
||||
"description": "Explore",
|
||||
"url": "/groups/:grouping*?/selector/:selector*?",
|
||||
"templateUrl": "components/dashboard/views/groups.html"
|
||||
},
|
||||
{
|
||||
"description": "Pod",
|
||||
"url": "/pods/:podId",
|
||||
"templateUrl": "components/dashboard/views/pod.html"
|
||||
}
|
||||
]
|
||||
}
|
1
www/app/components/dashboard/pages/footer.html
Normal file
1
www/app/components/dashboard/pages/footer.html
Normal file
@@ -0,0 +1 @@
|
||||
<p></p>
|
20
www/app/components/dashboard/pages/header.html
Normal file
20
www/app/components/dashboard/pages/header.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div layout-fill>
|
||||
<md-toolbar md-scroll-shrink class="dashboard-subnav">
|
||||
<div class="md-toolbar-tools">
|
||||
<div layout="row" flex class="fill-height">
|
||||
<div class="md-toolbar-item md-breadcrumb"></div>
|
||||
<span style="display: inline-block;">Kubernetes</span>
|
||||
<span flex></span>
|
||||
<div class="md-toolbar-item md-tools" layout="row">
|
||||
<div layout="column" class="selectSubPages">
|
||||
<md-select ng-model="page" placeholder="Views" class="selectTitle">
|
||||
<md-optgroup label="Dashboard">
|
||||
<md-option id="{{subpage.id}}" ng-value="subpage.value" ng-repeat="subpage in subpages | filter: {category: 'dashboard' }">{{subpage.name}}</md-option>
|
||||
</md-option-group>
|
||||
</md-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
</div>
|
7
www/app/components/dashboard/pages/home.html
Normal file
7
www/app/components/dashboard/pages/home.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard" ng-controller="DashboardCtrl" layout-fill>
|
||||
<md-content>
|
||||
<div ng-include="'components/dashboard/views/partials/cadvisor.html'">></div>
|
||||
</md-content>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
1
www/app/components/dashboard/protractor/smoke.spec.js
Normal file
1
www/app/components/dashboard/protractor/smoke.spec.js
Normal file
@@ -0,0 +1 @@
|
||||
describe("Kubernetes UI Dashboard",function(){it("should have all the expected components loaded",function(){browser.get("http://localhost:8000"),expect(browser.getTitle()).toEqual("Kubernetes UI");var e=element(by.id("tab_001"));expect(e).toBeDefined(),e.click(),expect(browser.getLocationAbsUrl()).toBe("/dashboard/");var t=element(by.model("page"));expect(t).toBeDefined()}),it("should have the subnav view",function(){browser.get("http://localhost:8000/"),expect(by.css(".dashboard-subnav")).toBeDefined();var e=element(by.css(".selectSubPages"));expect(e).toBeDefined(),e.click();var t=element(by.model("page"));expect(t).toBeDefined(),e.click(),t.click(),expect(element(by.id("groupsView"))).toBeDefined(),expect(element(by.id("podsView"))).toBeDefined(),expect(element(by.id("minionsView"))).toBeDefined(),expect(element(by.id("rcView"))).toBeDefined(),expect(element(by.id("servicesView"))).toBeDefined(),expect(element(by.id("eventsView"))).toBeDefined(),expect(element(by.id("cAdvisorView"))).toBeDefined()}),it("should have the cAdvisor view by default",function(){browser.get("http://localhost:8000/"),expect(browser.getTitle()).toEqual("Kubernetes UI"),expect(element.all(by.css(".dashboard")).count()).toBeGreaterThan(0),expect(element.all(by.css(".server-overview")).count()).toEqual(1),expect(element(by.repeater("minion in minions.items"))).toBeDefined();var e=element(by.css("svg"));expect(e).toBeDefined()}),it("should have the correct subviews",function(){browser.get("http://localhost:8000/");for(var e=["podsView","minionsView","rcView","servicesView","eventsView"],t=0;t<e.length;t++){var o=e[t],i=element(by.model("page"));i.click();var n=element(by.id(o));expect(n).toBeDefined(),n.click(),expect(browser.getTitle()).toEqual("Kubernetes UI"),expect(by.css(".dashboard-subnav")).toBeDefined(),expect(element(by.css(".selectSubPages"))).toBeDefined();var c=element(by.model("page"));expect(c).toBeDefined(),expect(element.all(by.css(".list-pods")).count()).toEqual(1),expect(element(by.repeater("h in headers"))).toBeDefined()}}),it("should have the correct groups view",function(){browser.get("http://localhost:8000/");var e=element(by.model("page"));e.click();var t=element(by.id("groupsView"));expect(t).toBeDefined(),t.click(),expect(browser.getTitle()).toEqual("Kubernetes UI"),expect(by.css(".dashboard-subnav")).toBeDefined(),expect(element(by.css(".selectSubPages"))).toBeDefined();var o=element(by.model("page"));expect(o).toBeDefined();var e=element(by.model("selectedGroupBy"));expect(e).toBeDefined(),e.click(),expect(element(by.repeater("g in groupByOptions"))).toBeDefined()})});
|
34
www/app/components/dashboard/views/groups.html
Normal file
34
www/app/components/dashboard/views/groups.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="GroupCtrl" layout="column" class="body-wrapper groups">
|
||||
<md-content>
|
||||
<!-- page header -->
|
||||
<div class="header" layout="row">
|
||||
<div class="">Group by: </div>
|
||||
|
||||
<md-select placeholder="{{routeParams.grouping}}" class="select-group-by" ng-model="selectedGroupBy" ng-change="changeGroupBy()">
|
||||
<md-option ng-value="g.value" ng-repeat="g in groupByOptions">{{g.name}}</md-option>
|
||||
</md-select>
|
||||
|
||||
<div ng-if="selector" layout="row" class="selector-area">
|
||||
<div class="filter-label">Filter:</div>
|
||||
|
||||
<div class="filter-text">{{selector}}</div>
|
||||
<div class="filter-area" ng-if="selector && selector.length > 0">
|
||||
|
||||
<button ng-click="clearSelector(routeParams.grouping)" class="md-button cancel-button">
|
||||
|
||||
<md-icon md-svg-src="components/dashboard/img/icons/ic_close_18px.svg" class="cancel-icon" alt="Cancel"></md-icon>
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="group-item" ng-repeat="(groupName,group) in groups.items" ng-include="'components/dashboard/views/partials/groupBox.html'"></div>
|
||||
</md-content>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
7
www/app/components/dashboard/views/listEvents.html
Normal file
7
www/app/components/dashboard/views/listEvents.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListEventsCtrl" style="padding:25px;" class="list-pods">
|
||||
<md-table headers="headers" content="content" sortable="sortable" filters="search" custom-class="custom" thumbs="thumbs" count="count"></md-table>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
7
www/app/components/dashboard/views/listMinions.html
Normal file
7
www/app/components/dashboard/views/listMinions.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListMinionsCtrl" style="padding:25px;" class="list-pods">
|
||||
<md-table headers="headers" content="content" sortable="sortable" filters="search" custom-class="custom" thumbs="thumbs" count="count"></md-table>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
7
www/app/components/dashboard/views/listPods.html
Normal file
7
www/app/components/dashboard/views/listPods.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListPodsCtrl" style="padding:25px;" class="list-pods">
|
||||
<md-table headers="headers" content="content" sortable="sortable" filters="search" custom-class="custom" thumbs="thumbs" count="count"></md-table>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
59
www/app/components/dashboard/views/listPodsCards.html
Normal file
59
www/app/components/dashboard/views/listPodsCards.html
Normal file
@@ -0,0 +1,59 @@
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListPodsCtrl" style="padding:25px;" class="list-pods">
|
||||
|
||||
<md-whiteframe layout-margin class="md-whiteframe-z2">
|
||||
<md-toolbar class="">
|
||||
<div class="md-toolbar-tools">
|
||||
Pods
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-content>
|
||||
|
||||
|
||||
<div class="pod-group">
|
||||
<md-grid-list md-cols="6" md-row-height="1:1.5" md-gutter="8px" ng-repeat="(podName, groupPods) in groupedPods">
|
||||
<md-grid-tile md-rowspan="1" md-colspan="2" class="gray">
|
||||
<md-grid-tile-footer>
|
||||
<div class="pod-title"><h2>{{podName}}</h2></div>
|
||||
</md-grid-tile-footer>
|
||||
</md-grid-tile>
|
||||
|
||||
<md-grid-tile class="purple" md-rowspan="1" md-colspan="1" ng-repeat="pod in groupPods" >
|
||||
<div>
|
||||
|
||||
<div>
|
||||
Containers:
|
||||
<span ng-repeat="container in pod.desiredState.manifest.containers">
|
||||
{{container.name}}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
Images:
|
||||
<span ng-repeat="container in pod.desiredState.manifest.containers">
|
||||
{{container.image}}
|
||||
</span>
|
||||
</div>
|
||||
<div>Internal IP: {{pod.currentState.podIP}}</div>
|
||||
<div>
|
||||
Labels:
|
||||
<span ng-repeat="(label, value) in pod.labels">{{label}}={{value}}<span ng-show="!$last">, </span></span>
|
||||
</div>
|
||||
<div>Status: {{pod.currentState.status}}</div>
|
||||
</div>
|
||||
<md-grid-tile-footer>
|
||||
|
||||
<div class="pod-host">{{pod.currentState.host}}</div>
|
||||
<div><a ng-href="/#/dashboard/pods/{{ pod.id }}"><h3>{{ pod.id }}</h3></a></div>
|
||||
|
||||
</md-grid-tile-footer>
|
||||
</md-grid-tile>
|
||||
|
||||
</md-grid-list>
|
||||
</div>
|
||||
|
||||
|
||||
</md-content>
|
||||
</md-whiteframe>
|
||||
|
||||
</div>
|
||||
</div>
|
17
www/app/components/dashboard/views/listPodsVisualizer.html
Normal file
17
www/app/components/dashboard/views/listPodsVisualizer.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListPodsCtrl" style="padding:25px;" class="list-pods">
|
||||
<md-whiteframe layout-margin class="md-whiteframe-z2">
|
||||
<md-content>
|
||||
<div>
|
||||
<md-button class="md-primary" ng-click="serverView = false">By Name</md-button> |
|
||||
<md-button class="md-primary" ng-click="serverView = true">By Server</md-button>
|
||||
<div style="float:right;"><md-button class="md-primary" ng-href="/#/dashboard/pods">View Pod Listing</md-button></div>
|
||||
</div>
|
||||
<div class="pod-group" ng-show="!serverView" ng-include="'components/dashboard/views/partials/podTilesByName.html'"></div>
|
||||
<div class="pod-group" ng-show="serverView" ng-include="'components/dashboard/views/partials/podTilesByServer.html'"></div>
|
||||
</md-content>
|
||||
</md-whiteframe>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
@@ -0,0 +1,7 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListReplicationControllersCtrl" style="padding:25px;" class="list-pods">
|
||||
<md-table headers="headers" content="content" sortable="sortable" filters="search" custom-class="custom" thumbs="thumbs" count="count"></md-table>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
7
www/app/components/dashboard/views/listServices.html
Normal file
7
www/app/components/dashboard/views/listServices.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ListServicesCtrl" style="padding:25px;" class="list-pods">
|
||||
<md-table headers="headers" content="content" sortable="sortable" filters="search" custom-class="custom" thumbs="thumbs" count="count"></md-table>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
@@ -0,0 +1,9 @@
|
||||
<div class="dashboard" ng-controller="cAdvisorController">
|
||||
<div class="server-overview">
|
||||
<md-content layout="row" layout-wrap>
|
||||
<div flex-sm="100" flex-md="50" flex-lg="33" flex-gt-lg="25" class="chart_area" ng-repeat="minion in minions.items">
|
||||
<d3-minion-bar-gauge data="activeMinionDataById[minion.id]" class="concentric" graph-width="325" graph-height="325" thickness=18 />
|
||||
</div>
|
||||
</md-content>
|
||||
</div>
|
||||
</div>
|
20
www/app/components/dashboard/views/partials/groupBox.html
Normal file
20
www/app/components/dashboard/views/partials/groupBox.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div>
|
||||
<md-content>
|
||||
<div class="server-overview" layout="column">
|
||||
<!-- subheader -->
|
||||
<div class="group-heading" layout="row">
|
||||
<div class="label">{{routeParams.grouping | ucfirst}}: <span class="bold">{{ (groupName) || "blank" }}</span></div>
|
||||
</div>
|
||||
<!-- render group data -->
|
||||
<div ng-include="'components/dashboard/views/partials/groupItem.html'"></div>
|
||||
<div class="footer">
|
||||
<!-- Alternate box inside a box -->
|
||||
<div ng-if="group.kind == 'grouping'">
|
||||
{{group.kind}}
|
||||
<div ng-repeat="(groupName,group) in group.items" ng-include="'components/dashboard/views/partials/groupBox.html'"></div>
|
||||
</div>
|
||||
<md-divider></md-divider>
|
||||
</div>
|
||||
</div>
|
||||
</md-content>
|
||||
</div>
|
42
www/app/components/dashboard/views/partials/groupItem.html
Normal file
42
www/app/components/dashboard/views/partials/groupItem.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<div layout="row" ng-if="group.kind != 'grouping'">
|
||||
<div>
|
||||
<!-- Default box display -->
|
||||
<div layout="row" class="group-item" ng-repeat="(groupType, data) in group | groupBy: 'labels.type'">
|
||||
<!-- left image -->
|
||||
<div class="icon-area">
|
||||
<div class="group-icon" style="background-color: {{getGroupColor(groupType)}}"></div>
|
||||
</div>
|
||||
<!-- right area -->
|
||||
<div class="group-main-area" layout="column">
|
||||
<!-- type -->
|
||||
<div class="subtype">
|
||||
{{groupType | ucfirst}}s
|
||||
</div>
|
||||
<!-- links -->
|
||||
<div layout="row" layout-wrap>
|
||||
<div layout="row" ng-repeat="item in data">
|
||||
<!-- title -->
|
||||
<div ng-switch on='item.labels["type"]'>
|
||||
<div class="group-name">
|
||||
<a ng-switch-when='pod' ng-href="/#/dashboard/pods/{{ item.id }}">{{ item.id }}</a>
|
||||
<a ng-switch-when='service' ng-href="/#/dashboard/services/{{ item.id }}">{{ item.id }}</a>
|
||||
<a ng-switch-when='replicationController' ng-href="/#/dashboard/replicationcontrollers/{{ item.id }}">{{ item.id }}</a>
|
||||
<div ng-switch-default>{{item.id}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<md-select ng-model="selectedFilter" ng-change="changeFilterBy(selectedFilter)" class="selectFilter">
|
||||
<md-optgroup label="FILTER">
|
||||
<md-option ng-value="'{{key}}={{value}}'" ng-repeat="(key, value) in item.labels">{{key}}: {{value}}</md-option>
|
||||
</md-option-group>
|
||||
</md-optgroup>
|
||||
</md-select>
|
||||
<!-- This is the official button design, but requires a custom dialog. Fix up after the demo. -->
|
||||
<!-- <md-button ng-click="" class="filter-button" style="padding:0">
|
||||
<md-icon md-svg-src="components/dashboard/img/icons/ic_arrow_drop_down_18px.svg" class="filter-icon" aria-label="" alt="Filter"></md-icon>
|
||||
</md-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,34 @@
|
||||
|
||||
<md-grid-list class="list-color-{{$index + 1}}" md-cols="6" md-row-height="1:1" md-gutter="8px" ng-repeat="(podName, groupPods) in podsByName">
|
||||
<md-grid-tile md-rowspan="2" md-colspan="2" class="colored">
|
||||
<md-grid-tile-footer>
|
||||
<div class="pod-title"><h2>{{podName}} overview</h2></div>
|
||||
</md-grid-tile-footer>
|
||||
</md-grid-tile>
|
||||
|
||||
<md-grid-tile class="colored {{podStatusClass(pod)}}" md-rowspan="1" md-colspan="1" ng-repeat="pod in groupPods" >
|
||||
<md-grid-tile-header class="clear-bg">
|
||||
|
||||
<div layout="row">
|
||||
<div class="labels"><span ng-repeat="(label, value) in otherLabels(pod.labels)">{{label}}: {{value}}<span ng-show="!$last">, </span></span></div>
|
||||
|
||||
<div flex="20" class="restarts" ng-show="getPodRestarts(pod) > 0">
|
||||
<md-button class="md-fab restart-button">
|
||||
{{getPodRestarts(pod)}}
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</md-grid-tile-header>
|
||||
<div class="inner-box">
|
||||
|
||||
<div ng-show="podStatusClass(pod)">Status: {{pod.currentState.status}}</div>
|
||||
</div>
|
||||
<md-grid-tile-footer>
|
||||
|
||||
<div class="pod-host">{{pod.currentState.host}}</div>
|
||||
<div><a ng-href="/#/dashboard/pods/{{ pod.id }}"><h3>{{ pod.id }}</h3></a></div>
|
||||
|
||||
</md-grid-tile-footer>
|
||||
</md-grid-tile>
|
||||
</md-grid-list>
|
@@ -0,0 +1,34 @@
|
||||
<md-grid-list class="" md-cols="6" md-row-height="1:1" md-gutter="8px" ng-repeat="(serverIp, groupPods) in podsByServer">
|
||||
<md-grid-tile md-rowspan="2" md-colspan="2" class="gray">
|
||||
<md-grid-tile-footer>
|
||||
<div class="pod-title"><h2>{{serverIp}} overview</h2></div>
|
||||
</md-grid-tile-footer>
|
||||
</md-grid-tile>
|
||||
|
||||
<md-grid-tile class="color-{{podIndexFromName(pod)}} {{podStatusClass(pod)}}" md-rowspan="1" md-colspan="1" ng-repeat="pod in groupPods" >
|
||||
<md-grid-tile-header class="clear-bg">
|
||||
|
||||
<div layout="row">
|
||||
<div class="labels"><span ng-repeat="(label, value) in otherLabels(pod.labels)">{{label}}: {{value}}<span ng-show="!$last">, </span></span></div>
|
||||
|
||||
<div flex="20" class="restarts" ng-show="getPodRestarts(pod) > 0">
|
||||
<md-button class="md-fab restart-button">
|
||||
{{getPodRestarts(pod)}}
|
||||
</md-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</md-grid-tile-header>
|
||||
<div class="inner-box">
|
||||
|
||||
<div ng-show="podStatusClass(pod)">Status: {{pod.currentState.status}}</div>
|
||||
</div>
|
||||
<md-grid-tile-footer>
|
||||
|
||||
<div class="pod-host">{{pod.labels.name}}</div>
|
||||
<div><a ng-href="/#/dashboard/pods/{{ pod.id }}"><h3>{{ pod.id }}</h3></a></div>
|
||||
|
||||
</md-grid-tile-footer>
|
||||
</md-grid-tile>
|
||||
|
||||
</md-grid-list>
|
97
www/app/components/dashboard/views/pod.html
Normal file
97
www/app/components/dashboard/views/pod.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="PodCtrl" layout="column" class="body-wrapper pod">
|
||||
<div class="detail">
|
||||
|
||||
<div class="back">
|
||||
<div class="nav-back">
|
||||
<a ng-click="doTheBack()">BACK</a>
|
||||
</div>
|
||||
<!-- <md-button class="md-default-theme" ng-click="doTheBack">BACK</md-button> -->
|
||||
</div>
|
||||
|
||||
<div class="heading">
|
||||
<span class="label">Pod:</span>
|
||||
<span>{{pod.id}}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="name">Status</td>
|
||||
<td class="value">
|
||||
{{pod.currentState.status}} on <a ng-href="/#/dashboard/groups/host/selector/host={{pod.currentState.host}}">{{pod.currentState.host}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Created</td>
|
||||
<td class="value">
|
||||
{{pod.creationTimestamp | date:'medium'}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Pod Networking</td>
|
||||
<td class="value">
|
||||
{{pod.currentState.podIP}}
|
||||
<span ng-repeat="container in pod.desiredState.manifest.containers">
|
||||
<span ng-repeat="port in container.ports">
|
||||
: {{port.containerPort}}
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Host Networking</td>
|
||||
<td class="value">
|
||||
{{pod.currentState.hostIP}}
|
||||
<span ng-repeat="container in pod.desiredState.manifest.containers">
|
||||
<span ng-repeat="port in container.ports">
|
||||
:{{port.hostPort}}
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Labels</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in pod.labels">
|
||||
{{label}}: {{value}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Containers</td>
|
||||
<td class="value">
|
||||
|
||||
<table class="containerTable">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>Image</td>
|
||||
<td>Restarts</td>
|
||||
</tr>
|
||||
<tr ng-repeat="container in pod.desiredState.manifest.containers">
|
||||
<td>{{container.name}}</td>
|
||||
<td>{{container.image}}</td>
|
||||
<td>{{pod.currentState.info[container.name].restartCount}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
82
www/app/components/dashboard/views/replication.html
Normal file
82
www/app/components/dashboard/views/replication.html
Normal file
@@ -0,0 +1,82 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ReplicationControllerCtrl" layout="column" class="body-wrapper">
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<div class="back">
|
||||
<md-button class="md-default-theme" ng-href="/#/dashboard/replicationcontrollers">‹ BACK</md-button>
|
||||
</div>
|
||||
|
||||
<div class="heading">
|
||||
<span class="label">Replication Controller: </span>
|
||||
<span>{{replicationController.id}}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="name">Created</td>
|
||||
<td class="value">
|
||||
{{replicationController.creationTimestamp | date:'medium'}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Desired Replicas</td>
|
||||
<td class="value">
|
||||
{{replicationController.desiredState.replicas}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Current Replicas</td>
|
||||
<td class="value">
|
||||
{{replicationController.currentState.replicas}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Labels</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in replicationController.labels">
|
||||
{{label}}: {{value}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Related Pods</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in replicationController.desiredState.replicaSelector">
|
||||
<a ng-href="/#/dashboard/groups/type/selector/{{label}}={{value}},type=pod">{{label}}: {{value}}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="name">Related Services</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in replicationController.desiredState.replicaSelector">
|
||||
<a ng-href="/#/dashboard/groups/type/selector/{{label}}={{value}},type=service">{{label}}: {{value}}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
97
www/app/components/dashboard/views/service.html
Normal file
97
www/app/components/dashboard/views/service.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<div dashboard-header></div>
|
||||
<div class="dashboard">
|
||||
<div ng-controller="ServiceCtrl" layout="column" class="body-wrapper service">
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<div class="back">
|
||||
<md-button class="md-default-theme" ng-href="/#/dashboard/services">‹ BACK</md-button>
|
||||
</div>
|
||||
|
||||
<div class="heading">
|
||||
<span class="label">Service: </span>
|
||||
<span>{{service.id}}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="name">Created</td>
|
||||
<td class="value">
|
||||
{{service.creationTimestamp | date:'medium'}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Port</td>
|
||||
<td class="value">
|
||||
{{service.port}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Container Port</td>
|
||||
<td class="value">
|
||||
{{service.containerPort}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Portal IP</td>
|
||||
<td class="value">
|
||||
{{service.portalIP}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Protocol</td>
|
||||
<td class="value">
|
||||
{{service.protocol}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Session Affinity</td>
|
||||
<td class="value">
|
||||
{{service.sessionAffinity}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Labels</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in service.labels">
|
||||
{{label}}: {{value}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Related Pods</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in service.selector">
|
||||
<a ng-href="/#/dashboard/groups/type/selector/{{label}}={{value}},type=pod">{{label}}: {{value}}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="name">Related Replication Controllers</td>
|
||||
<td class="value">
|
||||
<div ng-repeat="(label, value) in service.selector">
|
||||
<a ng-href="/#/dashboard/groups/type/selector/{{label}}={{value}},type=replicationController">{{label}}: {{value}}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div dashboard-footer></div>
|
Reference in New Issue
Block a user