mirror of https://github.com/portainer/portainer
feat(ux): normalize quick actions buttons (#2389)
* feat(ux): normalize quick actions buttons Fixes #2013 * fix(ux): fix wrong naming of variablepull/2421/head
parent
8df64031e8
commit
78bf374548
|
@ -0,0 +1,44 @@
|
||||||
|
<div class="btn-group btn-group-xs" role="group" aria-label="..." style="display:inline-flex;">
|
||||||
|
<a
|
||||||
|
ng-if="$ctrl.state.showQuickActionLogs && $ctrl.taskId === undefined"
|
||||||
|
style="margin: 0 2.5px;"
|
||||||
|
ui-sref="docker.containers.container.logs({id: $ctrl.containerId, nodeName: $ctrl.nodeName})"
|
||||||
|
title="Logs">
|
||||||
|
<i class="fa fa-file-alt space-right" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
ng-if="$ctrl.state.showQuickActionLogs && $ctrl.taskId !== undefined"
|
||||||
|
style="margin: 0 2.5px;"
|
||||||
|
ui-sref="docker.tasks.task.logs({id: $ctrl.taskId})"
|
||||||
|
title="Logs">
|
||||||
|
<i class="fa fa-file-alt space-right" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
ng-if="$ctrl.state.showQuickActionInspect && $ctrl.taskId === undefined"
|
||||||
|
style="margin: 0 2.5px;"
|
||||||
|
ui-sref="docker.containers.container.inspect({id: $ctrl.containerId, nodeName: $ctrl.nodeName})"
|
||||||
|
title="Inspect">
|
||||||
|
<i class="fa fa-info-circle space-right" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
ng-if="$ctrl.state.showQuickActionInspect && $ctrl.taskId !== undefined"
|
||||||
|
style="margin: 0 2.5px;"
|
||||||
|
ui-sref="docker.tasks.task({id: $ctrl.taskId})"
|
||||||
|
title="Inspect">
|
||||||
|
<i class="fa fa-info-circle space-right" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
ng-if="$ctrl.state.showQuickActionStats && ['starting', 'running', 'healthy', 'unhealthy'].indexOf($ctrl.status) !== -1"
|
||||||
|
style="margin: 0 2.5px;"
|
||||||
|
ui-sref="docker.containers.container.stats({id: $ctrl.containerId, nodeName: $ctrl.nodeName})"
|
||||||
|
title="Stats">
|
||||||
|
<i class="fa fa-chart-area space-right" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
ng-if="$ctrl.state.showQuickActionConsole && ['starting', 'running', 'healthy', 'unhealthy'].indexOf($ctrl.status) !== -1"
|
||||||
|
style="margin: 0 2.5px;"
|
||||||
|
ui-sref="docker.containers.container.console({id: $ctrl.containerId, nodeName: $ctrl.nodeName})"
|
||||||
|
title="Console">
|
||||||
|
<i class="fa fa-terminal space-right" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
|
@ -0,0 +1,10 @@
|
||||||
|
angular.module('portainer.docker').component('containerQuickActions', {
|
||||||
|
templateUrl: 'app/docker/components/container-quick-actions/containerQuickActions.html',
|
||||||
|
bindings: {
|
||||||
|
containerId: '<',
|
||||||
|
nodeName: '<',
|
||||||
|
status: '<',
|
||||||
|
state: '<',
|
||||||
|
taskId: '<'
|
||||||
|
}
|
||||||
|
});
|
|
@ -222,12 +222,7 @@
|
||||||
<span ng-if="['starting','healthy','unhealthy'].indexOf(item.Status) === -1" class="label label-{{ item.Status|containerstatusbadge }}">{{ item.Status }}</span>
|
<span ng-if="['starting','healthy','unhealthy'].indexOf(item.Status) === -1" class="label label-{{ item.Status|containerstatusbadge }}">{{ item.Status }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="!$ctrl.offlineMode && ($ctrl.settings.showQuickActionStats || $ctrl.settings.showQuickActionLogs || $ctrl.settings.showQuickActionConsole || $ctrl.settings.showQuickActionInspect)" ng-show="$ctrl.columnVisibility.columns.actions.display">
|
<td ng-if="!$ctrl.offlineMode && ($ctrl.settings.showQuickActionStats || $ctrl.settings.showQuickActionLogs || $ctrl.settings.showQuickActionConsole || $ctrl.settings.showQuickActionInspect)" ng-show="$ctrl.columnVisibility.columns.actions.display">
|
||||||
<div class="btn-group btn-group-xs" role="group" aria-label="..." style="display:inline-flex;">
|
<container-quick-actions container-id="item.Id" node-name="item.NodeName" status="item.Status" state="$ctrl.settings"></container-quick-actions>
|
||||||
<a ng-if="$ctrl.settings.showQuickActionStats" style="margin: 0 2.5px;" ui-sref="docker.containers.container.stats({id: item.Id, nodeName: item.NodeName})" title="Stats"><i class="fa fa-chart-area space-right" aria-hidden="true"></i></a>
|
|
||||||
<a ng-if="$ctrl.settings.showQuickActionLogs" style="margin: 0 2.5px;" ui-sref="docker.containers.container.logs({id: item.Id, nodeName: item.NodeName})" title="Logs"><i class="fa fa-file-alt space-right" aria-hidden="true"></i></a>
|
|
||||||
<a ng-if="$ctrl.settings.showQuickActionConsole" style="margin: 0 2.5px;" ui-sref="docker.containers.container.console({id: item.Id, nodeName: item.NodeName})" title="Console"><i class="fa fa-terminal space-right" aria-hidden="true"></i></a>
|
|
||||||
<a ng-if="$ctrl.settings.showQuickActionInspect" style="margin: 0 2.5px;" ui-sref="docker.containers.container.inspect({id: item.Id, nodeName: item.NodeName})" title="Inspect"><i class="fa fa-info-circle space-right" aria-hidden="true"></i></a>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="$ctrl.offlineMode">
|
<td ng-if="$ctrl.offlineMode">
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -64,11 +64,8 @@
|
||||||
<a ng-if="$ctrl.agentProxy && item.Container" ui-sref="docker.containers.container({ id: item.Container.Id, nodeName: item.Container.NodeName })" class="monospaced">{{ item.Id }}Doz</a>
|
<a ng-if="$ctrl.agentProxy && item.Container" ui-sref="docker.containers.container({ id: item.Container.Id, nodeName: item.Container.NodeName })" class="monospaced">{{ item.Id }}Doz</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group btn-group-xs" role="group" aria-label="..." >
|
<container-quick-actions ng-if="!$ctrl.agentProxy || !item.Container" container-id="item.ContainerId" task-id="item.Id" status="item.Status.State" state="$ctrl.state"></container-quick-actions>
|
||||||
<a style="margin: 0 2.5px;" ui-sref="docker.containers.container.logs({ id: item.Container.Id, nodeName: item.Container.NodeName })" title="Logs" ng-if="$ctrl.agentProxy && item.Container.Id"><i class="fa fa-file-alt space-right" aria-hidden="true"></i></a>
|
<container-quick-actions ng-if="$ctrl.agentProxy && item.Container" container-id="item.Container.Id" node-name="item.Container.NodeName" status="item.Status.State" state="$ctrl.state"></container-quick-actions>
|
||||||
<a style="margin: 0 2.5px;" ui-sref="docker.tasks.task.logs({ id: item.Id })" title="Logs" ng-if="!$ctrl.agentProxy && $ctrl.showTaskLogsButton && item.Status.State|taskhaslogs"><i class="fa fa-file-alt space-right" aria-hidden="true"></i></a>
|
|
||||||
<a style="margin: 0 2.5px;" ui-sref="docker.containers.container.console({ id: item.Container.Id, nodeName: item.Container.NodeName })" title="Console" ng-if="$ctrl.agentProxy && item.Status.State === 'running'"><i class="fa fa-terminal space-right" aria-hidden="true"></i></a>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td>{{ item.Slot ? item.Slot : '-' }}</td>
|
<td>{{ item.Slot ? item.Slot : '-' }}</td>
|
||||||
<td>{{ item.NodeId | tasknodename: $ctrl.nodes }}</td>
|
<td>{{ item.NodeId | tasknodename: $ctrl.nodes }}</td>
|
||||||
|
|
|
@ -4,7 +4,11 @@ function (DatatableService) {
|
||||||
var ctrl = this;
|
var ctrl = this;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
orderBy: this.orderBy
|
orderBy: this.orderBy,
|
||||||
|
showQuickActionStats: true,
|
||||||
|
showQuickActionLogs: true,
|
||||||
|
showQuickActionConsole: true,
|
||||||
|
showQuickActionInspect: true
|
||||||
};
|
};
|
||||||
|
|
||||||
this.filters = {
|
this.filters = {
|
||||||
|
|
|
@ -14,13 +14,6 @@
|
||||||
<table class="table table-hover nowrap-cells">
|
<table class="table table-hover nowrap-cells">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
|
||||||
<a ng-click="$ctrl.changeOrderBy('Id')">
|
|
||||||
Id
|
|
||||||
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Id' && !$ctrl.state.reverseOrder"></i>
|
|
||||||
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Id' && $ctrl.state.reverseOrder"></i>
|
|
||||||
</a>
|
|
||||||
</th>
|
|
||||||
<th>
|
<th>
|
||||||
<a ng-click="$ctrl.changeOrderBy('Status')">
|
<a ng-click="$ctrl.changeOrderBy('Status')">
|
||||||
Status
|
Status
|
||||||
|
@ -28,6 +21,14 @@
|
||||||
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Status' && $ctrl.state.reverseOrder"></i>
|
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Status' && $ctrl.state.reverseOrder"></i>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
|
<th>
|
||||||
|
<a ng-click="$ctrl.changeOrderBy('Id')">
|
||||||
|
Id
|
||||||
|
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Id' && !$ctrl.state.reverseOrder"></i>
|
||||||
|
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Id' && $ctrl.state.reverseOrder"></i>
|
||||||
|
</a>
|
||||||
|
</th>
|
||||||
|
<th>Actions</th>
|
||||||
<th ng-if="$ctrl.showSlotColumn">
|
<th ng-if="$ctrl.showSlotColumn">
|
||||||
<a ng-click="$ctrl.changeOrderBy('Slot')">
|
<a ng-click="$ctrl.changeOrderBy('Slot')">
|
||||||
Slot
|
Slot
|
||||||
|
@ -49,24 +50,22 @@
|
||||||
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Updated' && $ctrl.state.reverseOrder"></i>
|
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Updated' && $ctrl.state.reverseOrder"></i>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit))" ng-class="{active: item.Checked}">
|
<tr dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit))" ng-class="{active: item.Checked}">
|
||||||
|
<td><span class="label label-{{ item.Status.State | taskstatusbadge }}">{{ item.Status.State }}</span></td>
|
||||||
<td>
|
<td>
|
||||||
<a ng-if="!$ctrl.agentProxy || !item.Container" ui-sref="docker.tasks.task({id: item.Id})" class="monospaced">{{ item.ServiceName }}{{ item.Slot ? '.' + item.Slot : '' }}{{ '.' + item.Id }}</a>
|
<a ng-if="!$ctrl.agentProxy || !item.Container" ui-sref="docker.tasks.task({id: item.Id})" class="monospaced">{{ item.ServiceName }}{{ item.Slot ? '.' + item.Slot : '' }}{{ '.' + item.Id }}</a>
|
||||||
<a ng-if="$ctrl.agentProxy && item.Container" ui-sref="docker.containers.container({ id: item.Container.Id, nodeName: item.Container.NodeName })" class="monospaced">{{ item.ServiceName }}{{ item.Slot ? '.' + item.Slot : '' }}{{ '.' + item.Id }}</a>
|
<a ng-if="$ctrl.agentProxy && item.Container" ui-sref="docker.containers.container({ id: item.Container.Id, nodeName: item.Container.NodeName })" class="monospaced">{{ item.ServiceName }}{{ item.Slot ? '.' + item.Slot : '' }}{{ '.' + item.Id }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td><span class="label label-{{ item.Status.State | taskstatusbadge }}">{{ item.Status.State }}</span></td>
|
<td>
|
||||||
|
<container-quick-actions ng-if="!$ctrl.agentProxy || !item.Container" container-id="item.ContainerId" task-id="item.Id" status="item.Status.State" state="$ctrl.state"></container-quick-actions>
|
||||||
|
<container-quick-actions ng-if="$ctrl.agentProxy && item.Container" container-id="item.Container.Id" node-name="item.Container.NodeName" status="item.Status.State" state="$ctrl.state"></container-quick-actions>
|
||||||
|
</td>
|
||||||
<td ng-if="$ctrl.showSlotColumn">{{ item.Slot ? item.Slot : '-' }}</td>
|
<td ng-if="$ctrl.showSlotColumn">{{ item.Slot ? item.Slot : '-' }}</td>
|
||||||
<td>{{ item.NodeId | tasknodename: $ctrl.nodes }}</td>
|
<td>{{ item.NodeId | tasknodename: $ctrl.nodes }}</td>
|
||||||
<td>{{ item.Updated | getisodate }}</td>
|
<td>{{ item.Updated | getisodate }}</td>
|
||||||
<td>
|
|
||||||
<a ui-sref="docker.tasks.task.logs({ id: item.Id })" ng-if="!$ctrl.agentProxy && $ctrl.showLogsButton && item.Status.State|taskhaslogs"><i class="fa fa-file-alt" aria-hidden="true"></i> View logs</a>
|
|
||||||
<a ui-sref="docker.containers.container.logs({ id: item.Container.Id, nodeName: item.Container.NodeName })" ng-if="$ctrl.agentProxy && item.Status.State === 'running'"><i class="fa fa-file-alt" aria-hidden="true"></i> View logs</a>
|
|
||||||
<a ui-sref="docker.containers.container.console({ id: item.Container.Id, nodeName: item.Container.NodeName })" title="Console" ng-if="$ctrl.agentProxy"><i class="fa fa-terminal" aria-hidden="true"></i> Console</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-if="!$ctrl.dataset">
|
<tr ng-if="!$ctrl.dataset">
|
||||||
<td colspan="6" class="text-center text-muted">Loading...</td>
|
<td colspan="6" class="text-center text-muted">Loading...</td>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
angular.module('portainer.docker').component('tasksDatatable', {
|
angular.module('portainer.docker').component('tasksDatatable', {
|
||||||
templateUrl: 'app/docker/components/datatables/tasks-datatable/tasksDatatable.html',
|
templateUrl: 'app/docker/components/datatables/tasks-datatable/tasksDatatable.html',
|
||||||
controller: 'GenericDatatableController',
|
controller: 'TasksDatatableController',
|
||||||
bindings: {
|
bindings: {
|
||||||
titleText: '@',
|
titleText: '@',
|
||||||
titleIcon: '@',
|
titleIcon: '@',
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
angular.module('portainer.docker')
|
||||||
|
.controller('TasksDatatableController', ['PaginationService', 'DatatableService',
|
||||||
|
function (PaginationService, DatatableService) {
|
||||||
|
this.state = {
|
||||||
|
showQuickActionStats: true,
|
||||||
|
showQuickActionLogs: true,
|
||||||
|
showQuickActionConsole: true,
|
||||||
|
showQuickActionInspect: true,
|
||||||
|
selectAll: false,
|
||||||
|
orderBy: this.orderBy,
|
||||||
|
paginatedItemLimit: PaginationService.getPaginationLimit(this.tableKey),
|
||||||
|
displayTextFilter: false,
|
||||||
|
selectedItemCount: 0,
|
||||||
|
selectedItems: []
|
||||||
|
};
|
||||||
|
|
||||||
|
this.changeOrderBy = function(orderField) {
|
||||||
|
this.state.reverseOrder = this.state.orderBy === orderField ? !this.state.reverseOrder : false;
|
||||||
|
this.state.orderBy = orderField;
|
||||||
|
DatatableService.setDataTableOrder(this.tableKey, orderField, this.state.reverseOrder);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.selectItem = function(item) {
|
||||||
|
if (item.Checked) {
|
||||||
|
this.state.selectedItemCount++;
|
||||||
|
this.state.selectedItems.push(item);
|
||||||
|
} else {
|
||||||
|
this.state.selectedItems.splice(this.state.selectedItems.indexOf(item), 1);
|
||||||
|
this.state.selectedItemCount--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.selectAll = function() {
|
||||||
|
for (var i = 0; i < this.state.filteredDataSet.length; i++) {
|
||||||
|
var item = this.state.filteredDataSet[i];
|
||||||
|
if (item.Checked !== this.state.selectAll) {
|
||||||
|
item.Checked = this.state.selectAll;
|
||||||
|
this.selectItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.changePaginationLimit = function() {
|
||||||
|
PaginationService.setPaginationLimit(this.tableKey, this.state.paginatedItemLimit);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$onInit = function() {
|
||||||
|
setDefaults(this);
|
||||||
|
|
||||||
|
var storedOrder = DatatableService.getDataTableOrder(this.tableKey);
|
||||||
|
if (storedOrder !== null) {
|
||||||
|
this.state.reverseOrder = storedOrder.reverse;
|
||||||
|
this.state.orderBy = storedOrder.orderBy;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function setDefaults(ctrl) {
|
||||||
|
ctrl.showTextFilter = ctrl.showTextFilter ? ctrl.showTextFilter : false;
|
||||||
|
ctrl.state.reverseOrder = ctrl.reverseOrder ? ctrl.reverseOrder : false;
|
||||||
|
}
|
||||||
|
}]);
|
Loading…
Reference in New Issue