diff --git a/app/docker/components/datatables/networks-datatable/network-row-content/networkRowContent.html b/app/docker/components/datatables/networks-datatable/network-row-content/networkRowContent.html new file mode 100644 index 000000000..691569467 --- /dev/null +++ b/app/docker/components/datatables/networks-datatable/network-row-content/networkRowContent.html @@ -0,0 +1,27 @@ +
+ | + + + + | +Name @@ -145,30 +150,11 @@ | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
- - - - - {{ item.Name | truncate:40 }} - {{ item.Name | truncate:40 }} - | -{{ item.StackName ? item.StackName : '-' }} | -{{ item.Scope }} | -{{ item.Driver }} | -{{ item.Attachable }} | -{{ item.Internal }} | -{{ item.IPAM.Driver }} | -{{ item.IPAM.Config[0].Subnet ? item.IPAM.Config[0].Subnet : '-' }} | -{{ item.IPAM.Config[0].Gateway ? item.IPAM.Config[0].Gateway : '-' }} | -{{ item.NodeName ? item.NodeName : '-' }} | -- - - {{ item.ResourceControl.Ownership ? item.ResourceControl.Ownership : item.ResourceControl.Ownership = 'administrators' }} - - | +
Loading... | diff --git a/app/docker/components/datatables/networks-datatable/networksDatatableController.js b/app/docker/components/datatables/networks-datatable/networksDatatableController.js index f079bda46..7550111b4 100644 --- a/app/docker/components/datatables/networks-datatable/networksDatatableController.js +++ b/app/docker/components/datatables/networks-datatable/networksDatatableController.js @@ -1,3 +1,5 @@ +import _ from 'lodash-es'; + angular.module('portainer.docker') .controller('NetworksDatatableController', ['$scope', '$controller', 'PREDEFINED_NETWORKS', 'DatatableService', function ($scope, $controller, PREDEFINED_NETWORKS, DatatableService) { @@ -8,6 +10,10 @@ angular.module('portainer.docker') return PREDEFINED_NETWORKS.includes(item.Name); }; + this.state = Object.assign(this.state, { + expandedItems: [] + }) + /** * Do not allow PREDEFINED_NETWORKS to be selected */ @@ -47,5 +53,26 @@ angular.module('portainer.docker') } this.onSettingsRepeaterChange(); }; + + this.expandItem = function(item, expanded) { + item.Expanded = expanded; + }; + + this.itemCanExpand = function(item) { + return item.Subs.length > 0; + } + + this.hasExpandableItems = function() { + return _.filter(this.state.filteredDataSet, (item) => this.itemCanExpand(item)).length; + }; + + this.expandAll = function() { + this.state.expandAll = !this.state.expandAll; + _.forEach(this.state.filteredDataSet, (item) => { + if (this.itemCanExpand(item)) { + this.expandItem(item, this.state.expandAll); + } + }); + }; } ]); \ No newline at end of file diff --git a/app/docker/views/networks/networksController.js b/app/docker/views/networks/networksController.js index f2f79b395..6beb8da73 100644 --- a/app/docker/views/networks/networksController.js +++ b/app/docker/views/networks/networksController.js @@ -1,6 +1,8 @@ +import _ from 'lodash-es'; + angular.module('portainer.docker') -.controller('NetworksController', ['$scope', '$state', 'NetworkService', 'Notifications', 'HttpRequestHelper', 'EndpointProvider', -function ($scope, $state, NetworkService, Notifications, HttpRequestHelper, EndpointProvider) { +.controller('NetworksController', ['$q', '$scope', '$state', 'NetworkService', 'Notifications', 'HttpRequestHelper', 'EndpointProvider', 'AgentService', +function ($q, $scope, $state, NetworkService, Notifications, HttpRequestHelper, EndpointProvider, AgentService) { $scope.removeAction = function (selectedItems) { var actionCount = selectedItems.length; @@ -28,13 +30,43 @@ function ($scope, $state, NetworkService, Notifications, HttpRequestHelper, Endp $scope.getNetworks = getNetworks; + function groupSwarmNetworksManagerNodesFirst(networks, agents) { + const getRole = (item) => _.find(agents, (agent) => agent.NodeName === item.NodeName).NodeRole; + + const nonSwarmNetworks = _.remove(networks, (item) => item.Scope !== 'swarm') + const grouped = _.toArray(_.groupBy(networks, (item) => item.Id)); + const sorted = _.map(grouped, (arr) => _.sortBy(arr, (item) => getRole(item))); + const arr = _.map(sorted, (a) => { + const item = a[0]; + for (let i = 1; i < a.length; i++) { + item.Subs.push(a[i]); + } + return item; + }); + const res = _.concat(arr, ...nonSwarmNetworks); + return res; + } + function getNetworks() { - NetworkService.networks(true, true, true) - .then(function success(data) { - $scope.networks = data; + const req = { + networks: NetworkService.networks(true, true, true) + }; + + if ($scope.applicationState.endpoint.mode.agentProxy && $scope.applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE') { + req.agents = AgentService.agents(); + } + + $q.all(req) + .then((data) => { $scope.offlineMode = EndpointProvider.offlineMode(); + const networks = _.forEach(data.networks, (item) => item.Subs = []); + if ($scope.applicationState.endpoint.mode.agentProxy && $scope.applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE') { + $scope.networks = groupSwarmNetworksManagerNodesFirst(data.networks, data.agents); + } else { + $scope.networks = networks; + } }) - .catch(function error(err) { + .catch((err) => { $scope.networks = []; Notifications.error('Failure', err, 'Unable to retrieve networks'); });