You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mz...@apache.org on 2019/09/19 21:14:25 UTC
[mesos] branch master updated: Implemented displaying roles of
multi-role frameworks as a tree.
This is an automated email from the ASF dual-hosted git repository.
mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
The following commit(s) were added to refs/heads/master by this push:
new b13de7e Implemented displaying roles of multi-role frameworks as a tree.
b13de7e is described below
commit b13de7eee6eda644ddb136947a655b9d9439784e
Author: Andrei Sekretenko <as...@mesosphere.io>
AuthorDate: Thu Sep 19 14:13:57 2019 -0700
Implemented displaying roles of multi-role frameworks as a tree.
This patch makes the UI pages `frameworks` and `framework` display
roles of multi-role frameworks as collapsible tree (instead of a list).
Review: https://reviews.apache.org/r/71178/
---
src/webui/app/app.js | 78 +++++++++++++++++++++++++++
src/webui/app/frameworks/framework.html | 10 ++--
src/webui/app/frameworks/frameworks.html | 27 +++++-----
src/webui/app/frameworks/roles-tree-root.html | 7 +++
src/webui/app/frameworks/roles-tree.html | 16 ++++++
src/webui/app/frameworks/roles.html | 2 +
src/webui/assets/css/mesos.css | 41 ++++++++++++++
7 files changed, 160 insertions(+), 21 deletions(-)
diff --git a/src/webui/app/app.js b/src/webui/app/app.js
index f6f1138..24fab09 100644
--- a/src/webui/app/app.js
+++ b/src/webui/app/app.js
@@ -257,6 +257,84 @@
templateUrl: 'app/shared/timestamp.html'
}
}])
+ .directive('mFrameworkRoles', function() {
+ return {
+ restrict: 'E',
+ scope: {roles: '=', frameworkId: '='},
+ templateUrl: 'app/frameworks/roles.html'
+ }
+ })
+ .directive('mFrameworkRolesTree', function() {
+ // This helper builds a prefix tree from a list of roles.
+ // Each role from the list corresponds to a leaf node in the tree.
+ // The path to that leaf node equals to the role (with '/.' added if this
+ // path is a prefix of other roles).
+ //
+ // For example, given a list of roles ['a/b','a', 'e/f', 'e/g']
+ // the following tree will be built:
+ // {'a': {'.': {}, 'b' : {}}, 'e': {'f': {}, 'g': '{}'}}
+ // (corresponding paths are 'a/.', 'a/b', 'e/f' and 'e/g')
+ function buildTree(roles) {
+ var root = {};
+
+ for (var path of roles) {
+ const tokens = path.split('/');
+ var i = 0;
+ var node = root;
+ for (i = 0; i < tokens.length && (tokens[i] in node); ++i) {
+ node = node[tokens[i]];
+ }
+
+ if (i > 0 && (i == tokens.length || Object.keys(node).length == 0)) {
+ node['.'] = {};
+ }
+
+ for (; i < tokens.length; ++i) {
+ node[tokens[i]] = {};
+ node = node[tokens[i]];
+ }
+ }
+
+ return root;
+ };
+
+ function prepareTree(path, name, node) {
+ const prefix = path ? path + '/' : '';
+ return {
+ "children": Object.keys(node).sort().map(
+ k => prepareTree(prefix + k, k, node[k])),
+ "name": name,
+ "path": path
+ }
+ };
+
+ return {
+ restrict: 'E',
+ scope: {roles: '=', frameworkId: '='},
+ link: function($scope, _element, _attrs) {
+
+ // TODO (asekretenko): after MESOS-9915 consider getting the roles
+ // hierarchy from master directly (instead of buildTree()).
+ $scope.node = prepareTree("", "", buildTree($scope.roles));
+
+ $scope.storagePrefix = 'framework-roles-tree.' + $scope.frameworkId;
+ $scope.visible = JSON.parse(
+ localStorage.getItem($scope.storagePrefix) || '{}');
+
+ $scope.toggle = function(path) {
+ if (path in $scope.visible) {
+ delete $scope.visible[path];
+ } else {
+ $scope.visible[path] = true;
+ }
+
+ localStorage.setItem($scope.storagePrefix,
+ JSON.stringify($scope.visible));
+ };
+ },
+ templateUrl: 'app/frameworks/roles-tree-root.html'
+ }
+ })
.directive('mPagination', function() {
return { templateUrl: 'app/shared/pagination.html' }
})
diff --git a/src/webui/app/frameworks/framework.html b/src/webui/app/frameworks/framework.html
index 82f6b27..93ec74c 100644
--- a/src/webui/app/frameworks/framework.html
+++ b/src/webui/app/frameworks/framework.html
@@ -23,13 +23,11 @@
<dd ng-show="framework.webui_url"><a href="{{framework.webui_url}}">{{framework.webui_url}}</a></dd>
<dt>User:</dt>
<dd>{{framework.user}}</dd>
- <!-- TODO(bmahler): Consider having a break between each role
- in order to increase readability. Also, this doesn't
- display well when there are a lot of roles (e.g. a large
- organization with a lot of teams & services, using roles
- like /engineering/frontend/webserver, etc). -->
<dt>Roles:</dt>
- <dd>{{framework.roles.toString()}}</dd>
+ <dd>
+ <m-framework-roles framework-id="framework.id" roles="framework.roles">
+ </m-framework-roles>
+ </dd>
<dt>Principal:</dt>
<dd>{{framework.principal}}</dd>
<dt>Registered:</dt>
diff --git a/src/webui/app/frameworks/frameworks.html b/src/webui/app/frameworks/frameworks.html
index d37c613..737f407 100644
--- a/src/webui/app/frameworks/frameworks.html
+++ b/src/webui/app/frameworks/frameworks.html
@@ -45,11 +45,10 @@
</td>
<td>{{framework.user}}</td>
<td>{{framework.name}}</td>
- <!-- TODO(bmahler): This doesn't display well when there are a lot
- of roles (e.g. a large organization with a lot of teams &
- services, using roles like /engineering/frontend/webserver, etc).
- Figure out a way to display this without bloating the table. -->
- <td>{{framework.roles.toString()}}</td>
+ <td>
+ <m-framework-roles framework-id="framework.id" roles="framework.roles">
+ </m-framework-roles>
+ </td>
<td>{{framework.principal}}</td>
<td>{{framework.tasks.length}}</td>
<td>{{framework.used_resources.cpus | number}}</td>
@@ -108,11 +107,10 @@
</td>
<td>{{framework.user}}</td>
<td>{{framework.name}}</td>
- <!-- TODO(bmahler): This doesn't display well when there are a lot
- of roles (e.g. a large organization with a lot of teams &
- services, using roles like /engineering/frontend/webserver, etc).
- Figure out a way to display this without bloating the table. -->
- <td>{{framework.roles.toString()}}</td>
+ <td>
+ <m-framework-roles framework-id="framework.id" roles="framework.roles">
+ </m-framework-roles>
+ </td>
<td>{{framework.principal}}</td>
<td>{{framework.tasks.length}}</td>
<td>{{framework.used_resources.cpus | number}}</td>
@@ -162,11 +160,10 @@
<td>{{framework.hostname}}</td>
<td>{{framework.user}}</td>
<td>{{framework.name}}</td>
- <!-- TODO(bmahler): This doesn't display well when there are a lot
- of roles (e.g. a large organization with a lot of teams &
- services, using roles like /engineering/frontend/webserver, etc).
- Figure out a way to display this without bloating the table. -->
- <td>{{framework.roles.toString()}}</td>
+ <td>
+ <m-framework-roles framework-id="framework.id" roles="framework.roles">
+ </m-framework-roles>
+ </td>
<td>{{framework.principal}}</td>
<td>
<m-timestamp value="{{framework.registered_time * 1000}}"></m-timestamp>
diff --git a/src/webui/app/frameworks/roles-tree-root.html b/src/webui/app/frameworks/roles-tree-root.html
new file mode 100644
index 0000000..982aac1
--- /dev/null
+++ b/src/webui/app/frameworks/roles-tree-root.html
@@ -0,0 +1,7 @@
+<div ng-click="toggle('')" ng-class="visible[''] ? 'tree-expanded': 'tree-collapsed'">
+ <div class="tree-internal">
+ {{ roles.length }} roles
+ </div>
+</div>
+
+<ng-include ng-if="visible['']" src="'app/frameworks/roles-tree.html'"></ng-include>
diff --git a/src/webui/app/frameworks/roles-tree.html b/src/webui/app/frameworks/roles-tree.html
new file mode 100644
index 0000000..61bc055
--- /dev/null
+++ b/src/webui/app/frameworks/roles-tree.html
@@ -0,0 +1,16 @@
+<ul ng-class="node.path ? 'tree' : 'tree-root'">
+ <li ng-repeat="node in node.children">
+ <div ng-if="node.children.length == 0" class="tree-leaf">
+ {{ node.name }}
+ </div>
+
+ <div ng-if="node.children.length > 0" ng-click="toggle(node.path)" ng-class="visible[node.path] ? 'tree-expanded': 'tree-collapsed'">
+ <div class="tree-internal">
+ {{ node.name }}
+ </div>
+ </div>
+
+ <ng-include ng-if="node.children.length > 0 && visible[node.path]" src="'app/frameworks/roles-tree.html'">
+ </ng-include>
+ </li>
+</ul>
diff --git a/src/webui/app/frameworks/roles.html b/src/webui/app/frameworks/roles.html
new file mode 100644
index 0000000..54e3dfd
--- /dev/null
+++ b/src/webui/app/frameworks/roles.html
@@ -0,0 +1,2 @@
+<span ng-if='roles.length < 2'> {{roles.join(' ')}}</span>
+<m-framework-roles-tree ng-if='roles.length >= 2' framework-id="frameworkId" roles="roles">
diff --git a/src/webui/assets/css/mesos.css b/src/webui/assets/css/mesos.css
index 0ff47cd..5066414 100644
--- a/src/webui/assets/css/mesos.css
+++ b/src/webui/assets/css/mesos.css
@@ -129,6 +129,47 @@ time:hover {
cursor: pointer;
}
+ul.tree {
+ list-style-type: none;
+ padding-left: 1em;
+}
+
+ul.tree-root {
+ list-style-type: none;
+ padding-left: 0em;
+}
+
+div.tree-internal {
+ border-bottom: 1px #999 dashed;
+ display: inline-block;
+}
+
+div.tree-collapsed:hover,
+div.tree-expanded:hover {
+ cursor:pointer;
+}
+
+div.tree-collapsed:before,
+div.tree-expanded:before,
+div.tree-leaf:before {
+ width: 1em;
+ padding-right: 0.3em;
+ display: inline-block;
+ text-align: right;
+}
+
+div.tree-collapsed:before {
+ content: "▹";
+}
+
+div.tree-expanded:before {
+ content: "▿";
+}
+
+div.tree-leaf:before {
+ content: "•";
+}
+
.inline .btn-toggle,
.table-condensed .btn-toggle {
margin-bottom: -2px;