diff --git a/.gitignore b/.gitignore index 82995009b..b9f700a90 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ lazydocker* TODO.md Lazydocker.code-workspace .vscode +.idea diff --git a/docs/keybindings/Keybindings_de.md b/docs/keybindings/Keybindings_de.md index 913d88175..f463e21bd 100644 --- a/docs/keybindings/Keybindings_de.md +++ b/docs/keybindings/Keybindings_de.md @@ -81,6 +81,18 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct /: filter list +## Netzwerk + +
+  c: führe vordefinierten benutzerdefinierten Befehl aus
+  d: entferne Netzwerk
+  b: view bulk commands
+  enter: fokussieren aufs Hauptpanel
+  [: vorheriges Tab
+  ]: nächstes Tab
+  /: filter list
+
+ ## Haupt
diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md
index fe99e262a..a5a8ff3f0 100644
--- a/docs/keybindings/Keybindings_en.md
+++ b/docs/keybindings/Keybindings_en.md
@@ -81,6 +81,18 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
   /: filter list
 
+## Networks + +
+  c: run predefined custom command
+  d: remove network
+  b: view bulk commands
+  enter: focus main panel
+  [: previous tab
+  ]: next tab
+  /: filter list
+
+ ## Main
diff --git a/docs/keybindings/Keybindings_fr.md b/docs/keybindings/Keybindings_fr.md
index 07c1eac33..dcdbe19e9 100644
--- a/docs/keybindings/Keybindings_fr.md
+++ b/docs/keybindings/Keybindings_fr.md
@@ -81,6 +81,18 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
   /: filter list
 
+## Réseaux + +
+  c: executer une commande prédéfinie
+  d: supprimer le réseau
+  b: voir les commandes groupés
+  enter: focus paneau principal
+  [: onglet précédent
+  ]: onglet suivant
+  /: filter list
+
+ ## Principal
diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md
index 7f134edb3..3de0c93e8 100644
--- a/docs/keybindings/Keybindings_nl.md
+++ b/docs/keybindings/Keybindings_nl.md
@@ -81,6 +81,18 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
   /: filter list
 
+## Networks + +
+  c: draai een vooraf bedacht aangepaste opdracht
+  d: verwijder network
+  b: view bulk commands
+  enter: focus hoofdpaneel
+  [: vorige tab
+  ]: volgende tab
+  /: filter list
+
+ ## Hoofd
diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md
index b14a9b34a..0983b8e23 100644
--- a/docs/keybindings/Keybindings_pl.md
+++ b/docs/keybindings/Keybindings_pl.md
@@ -81,6 +81,18 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
   /: filter list
 
+## Seici + +
+  c: wykonaj predefiniowaną własną komende
+  d: usuń seici
+  b: view bulk commands
+  enter: skup na głównym panelu
+  [: poprzednia zakładka
+  ]: następna zakładka
+  /: filter list
+
+ ## Główne
diff --git a/docs/keybindings/Keybindings_tr.md b/docs/keybindings/Keybindings_tr.md
index bcb7ac1ca..018f68c28 100644
--- a/docs/keybindings/Keybindings_tr.md
+++ b/docs/keybindings/Keybindings_tr.md
@@ -81,6 +81,18 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
   /: filter list
 
+## Ağları + +
+  c: önceden tanımlanmış özel komutu çalıştır
+  d: ağı kaldır
+  b: view bulk commands
+  enter: ana panele odaklan
+  [: önceki sekme
+  ]: sonraki sekme
+  /: filter list
+
+ ## Ana
diff --git a/pkg/cheatsheet/generate.go b/pkg/cheatsheet/generate.go
index bd9d230c0..76e9875dc 100644
--- a/pkg/cheatsheet/generate.go
+++ b/pkg/cheatsheet/generate.go
@@ -96,6 +96,7 @@ func getBindingSections(mApp *app.App) []*bindingSection {
 			"containers": mApp.Tr.ContainersTitle,
 			"images":     mApp.Tr.ImagesTitle,
 			"volumes":    mApp.Tr.VolumesTitle,
+			"networks":   mApp.Tr.NetworksTitle,
 		}
 
 		bindingSections = addBinding(titleMap[viewName], bindingSections, binding)
diff --git a/pkg/commands/docker.go b/pkg/commands/docker.go
index 70f4e88d1..d7268a7d8 100644
--- a/pkg/commands/docker.go
+++ b/pkg/commands/docker.go
@@ -55,6 +55,7 @@ type CommandObject struct {
 	Container     *Container
 	Image         *Image
 	Volume        *Volume
+	Network       *Network
 }
 
 // NewCommandObject takes a command object and returns a default command object with the passed command object merged in
diff --git a/pkg/commands/network.go b/pkg/commands/network.go
new file mode 100644
index 000000000..c1c185934
--- /dev/null
+++ b/pkg/commands/network.go
@@ -0,0 +1,54 @@
+package commands
+
+import (
+	"context"
+
+	dockerTypes "github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/client"
+	"github.com/sirupsen/logrus"
+)
+
+// Network : A docker Network
+type Network struct {
+	Name          string
+	Network       dockerTypes.NetworkResource
+	Client        *client.Client
+	OSCommand     *OSCommand
+	Log           *logrus.Entry
+	DockerCommand LimitedDockerCommand
+}
+
+// RefreshNetworks gets the networks and stores them
+func (c *DockerCommand) RefreshNetworks() ([]*Network, error) {
+	networks, err := c.Client.NetworkList(context.Background(), dockerTypes.NetworkListOptions{})
+	if err != nil {
+		return nil, err
+	}
+
+	ownNetworks := make([]*Network, len(networks))
+
+	for i, network := range networks {
+		ownNetworks[i] = &Network{
+			Name:          network.Name,
+			Network:       network,
+			Client:        c.Client,
+			OSCommand:     c.OSCommand,
+			Log:           c.Log,
+			DockerCommand: c,
+		}
+	}
+
+	return ownNetworks, nil
+}
+
+// PruneNetworks prunes networks
+func (c *DockerCommand) PruneNetworks() error {
+	_, err := c.Client.NetworksPrune(context.Background(), filters.Args{})
+	return err
+}
+
+// Remove removes the network
+func (v *Network) Remove() error {
+	return v.Client.NetworkRemove(context.Background(), v.Name)
+}
diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go
index 87bc4f2ca..c3a0994a7 100644
--- a/pkg/config/app_config.go
+++ b/pkg/config/app_config.go
@@ -286,6 +286,9 @@ type CustomCommands struct {
 
 	// Volumes contains the custom commands for volumes
 	Volumes []CustomCommand `yaml:"volumes,omitempty"`
+
+	// Networks contains the custom commands for networks
+	Networks []CustomCommand `yaml:"networks,omitempty"`
 }
 
 // Replacements contains the stuff relating to rendering a container's info
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 1ffc88920..cbbe54142 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -56,6 +56,7 @@ type Panels struct {
 	Containers *panels.SideListPanel[*commands.Container]
 	Images     *panels.SideListPanel[*commands.Image]
 	Volumes    *panels.SideListPanel[*commands.Volume]
+	Networks   *panels.SideListPanel[*commands.Network]
 	Menu       *panels.SideListPanel[*types.MenuItem]
 }
 
@@ -273,6 +274,7 @@ func (gui *Gui) setPanels() {
 		Containers: gui.getContainersPanel(),
 		Images:     gui.getImagesPanel(),
 		Volumes:    gui.getVolumesPanel(),
+		Networks:   gui.getNetworksPanel(),
 		Menu:       gui.getMenuPanel(),
 	}
 }
@@ -297,6 +299,11 @@ func (gui *Gui) refresh() {
 			gui.Log.Error(err)
 		}
 	}()
+	go func() {
+		if err := gui.reloadNetworks(); err != nil {
+			gui.Log.Error(err)
+		}
+	}()
 	go func() {
 		if err := gui.reloadImages(); err != nil {
 			gui.Log.Error(err)
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 4c0864699..424f47c56 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -409,6 +409,27 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
 			Handler:     gui.handleVolumesBulkCommand,
 			Description: gui.Tr.ViewBulkCommands,
 		},
+		{
+			ViewName:    "networks",
+			Key:         'c',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleNetworksCustomCommand,
+			Description: gui.Tr.RunCustomCommand,
+		},
+		{
+			ViewName:    "networks",
+			Key:         'd',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleNetworksRemoveMenu,
+			Description: gui.Tr.RemoveNetwork,
+		},
+		{
+			ViewName:    "networks",
+			Key:         'b',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleNetworksBulkCommand,
+			Description: gui.Tr.ViewBulkCommands,
+		},
 		{
 			ViewName:    "main",
 			Key:         gocui.KeyEsc,
diff --git a/pkg/gui/networks_panel.go b/pkg/gui/networks_panel.go
new file mode 100644
index 000000000..4702d35dd
--- /dev/null
+++ b/pkg/gui/networks_panel.go
@@ -0,0 +1,179 @@
+package gui
+
+import (
+	"strconv"
+
+	"github.com/fatih/color"
+	"github.com/jesseduffield/gocui"
+	"github.com/jesseduffield/lazydocker/pkg/commands"
+	"github.com/jesseduffield/lazydocker/pkg/config"
+	"github.com/jesseduffield/lazydocker/pkg/gui/panels"
+	"github.com/jesseduffield/lazydocker/pkg/gui/presentation"
+	"github.com/jesseduffield/lazydocker/pkg/gui/types"
+	"github.com/jesseduffield/lazydocker/pkg/tasks"
+	"github.com/jesseduffield/lazydocker/pkg/utils"
+	"github.com/samber/lo"
+)
+
+func (gui *Gui) getNetworksPanel() *panels.SideListPanel[*commands.Network] {
+	return &panels.SideListPanel[*commands.Network]{
+		ContextState: &panels.ContextState[*commands.Network]{
+			GetMainTabs: func() []panels.MainTab[*commands.Network] {
+				return []panels.MainTab[*commands.Network]{
+					{
+						Key:    "config",
+						Title:  gui.Tr.ConfigTitle,
+						Render: gui.renderNetworkConfig,
+					},
+				}
+			},
+			GetItemContextCacheKey: func(network *commands.Network) string {
+				return "networks-" + network.Name
+			},
+		},
+		ListPanel: panels.ListPanel[*commands.Network]{
+			List: panels.NewFilteredList[*commands.Network](),
+			View: gui.Views.Networks,
+		},
+		NoItemsMessage: gui.Tr.NoNetworks,
+		Gui:            gui.intoInterface(),
+		// we're sorting these networks based on whether they have labels defined,
+		// because those are the ones you typically care about.
+		// Within that, we also sort them alphabetically
+		Sort: func(a *commands.Network, b *commands.Network) bool {
+			return a.Name < b.Name
+		},
+		GetTableCells: presentation.GetNetworkDisplayStrings,
+	}
+}
+
+func (gui *Gui) renderNetworkConfig(network *commands.Network) tasks.TaskFunc {
+	return gui.NewSimpleRenderStringTask(func() string { return gui.networkConfigStr(network) })
+}
+
+func (gui *Gui) networkConfigStr(network *commands.Network) string {
+	padding := 15
+	output := ""
+	output += utils.WithPadding("ID: ", padding) + network.Network.ID + "\n"
+	output += utils.WithPadding("Name: ", padding) + network.Name + "\n"
+	output += utils.WithPadding("Driver: ", padding) + network.Network.Driver + "\n"
+	output += utils.WithPadding("Scope: ", padding) + network.Network.Scope + "\n"
+	output += utils.WithPadding("EnabledIPV6: ", padding) + strconv.FormatBool(network.Network.EnableIPv6) + "\n"
+	output += utils.WithPadding("Internal: ", padding) + strconv.FormatBool(network.Network.Internal) + "\n"
+	output += utils.WithPadding("Attachable: ", padding) + strconv.FormatBool(network.Network.Attachable) + "\n"
+	output += utils.WithPadding("Ingress: ", padding) + strconv.FormatBool(network.Network.Ingress) + "\n"
+
+	output += utils.WithPadding("Containers: ", padding)
+	if len(network.Network.Containers) > 0 {
+		output += "\n"
+		for _, v := range network.Network.Containers {
+			output += utils.FormatMapItem(padding, v.Name, v.EndpointID)
+		}
+	} else {
+		output += "none\n"
+	}
+
+	output += "\n"
+	output += utils.WithPadding("Labels: ", padding) + utils.FormatMap(padding, network.Network.Labels) + "\n"
+	output += utils.WithPadding("Options: ", padding) + utils.FormatMap(padding, network.Network.Options)
+
+	return output
+}
+
+func (gui *Gui) reloadNetworks() error {
+	if err := gui.refreshStateNetworks(); err != nil {
+		return err
+	}
+
+	return gui.Panels.Networks.RerenderList()
+}
+
+func (gui *Gui) refreshStateNetworks() error {
+	networks, err := gui.DockerCommand.RefreshNetworks()
+	if err != nil {
+		return err
+	}
+
+	gui.Panels.Networks.SetItems(networks)
+
+	return nil
+}
+
+func (gui *Gui) handleNetworksRemoveMenu(g *gocui.Gui, v *gocui.View) error {
+	network, err := gui.Panels.Networks.GetSelectedItem()
+	if err != nil {
+		return nil
+	}
+
+	type removeNetworkOption struct {
+		description string
+		command     string
+	}
+
+	options := []*removeNetworkOption{
+		{
+			description: gui.Tr.Remove,
+			command:     utils.WithShortSha("docker network rm " + network.Name),
+		},
+	}
+
+	menuItems := lo.Map(options, func(option *removeNetworkOption, _ int) *types.MenuItem {
+		return &types.MenuItem{
+			LabelColumns: []string{option.description, color.New(color.FgRed).Sprint(option.command)},
+			OnPress: func() error {
+				return gui.WithWaitingStatus(gui.Tr.RemovingStatus, func() error {
+					if err := network.Remove(); err != nil {
+						return gui.createErrorPanel(err.Error())
+					}
+					return nil
+				})
+			},
+		}
+	})
+
+	return gui.Menu(CreateMenuOptions{
+		Title: "",
+		Items: menuItems,
+	})
+}
+
+func (gui *Gui) handlePruneNetworks() error {
+	return gui.createConfirmationPanel(gui.Tr.Confirm, gui.Tr.ConfirmPruneNetworks, func(g *gocui.Gui, v *gocui.View) error {
+		return gui.WithWaitingStatus(gui.Tr.PruningStatus, func() error {
+			err := gui.DockerCommand.PruneNetworks()
+			if err != nil {
+				return gui.createErrorPanel(err.Error())
+			}
+			return nil
+		})
+	}, nil)
+}
+
+func (gui *Gui) handleNetworksCustomCommand(g *gocui.Gui, v *gocui.View) error {
+	network, err := gui.Panels.Networks.GetSelectedItem()
+	if err != nil {
+		return nil
+	}
+
+	commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{
+		Network: network,
+	})
+
+	customCommands := gui.Config.UserConfig.CustomCommands.Networks
+
+	return gui.createCustomCommandMenu(customCommands, commandObject)
+}
+
+func (gui *Gui) handleNetworksBulkCommand(g *gocui.Gui, v *gocui.View) error {
+	baseBulkCommands := []config.CustomCommand{
+		{
+			Name:             gui.Tr.PruneNetworks,
+			InternalFunction: gui.handlePruneNetworks,
+		},
+	}
+
+	bulkCommands := append(baseBulkCommands, gui.Config.UserConfig.BulkCommands.Networks...)
+	commandObject := gui.DockerCommand.NewCommandObject(commands.CommandObject{})
+
+	return gui.createBulkCommandMenu(bulkCommands, commandObject)
+}
diff --git a/pkg/gui/presentation/networks.go b/pkg/gui/presentation/networks.go
new file mode 100644
index 000000000..88a29fc9f
--- /dev/null
+++ b/pkg/gui/presentation/networks.go
@@ -0,0 +1,7 @@
+package presentation
+
+import "github.com/jesseduffield/lazydocker/pkg/commands"
+
+func GetNetworkDisplayStrings(network *commands.Network) []string {
+	return []string{network.Network.Driver, network.Name}
+}
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 8ddae589b..5e2b72fb9 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -362,6 +362,7 @@ func (gui *Gui) allSidePanels() []panels.ISideListPanel {
 		gui.Panels.Containers,
 		gui.Panels.Images,
 		gui.Panels.Volumes,
+		gui.Panels.Networks,
 	}
 }
 
diff --git a/pkg/gui/views.go b/pkg/gui/views.go
index 05b9db5f0..efc0824d2 100644
--- a/pkg/gui/views.go
+++ b/pkg/gui/views.go
@@ -32,6 +32,7 @@ type Views struct {
 	Containers *gocui.View
 	Images     *gocui.View
 	Volumes    *gocui.View
+	Networks   *gocui.View
 
 	// main panel
 	Main *gocui.View
@@ -70,6 +71,7 @@ func (gui *Gui) orderedViewNameMappings() []viewNameMapping {
 		{viewPtr: &gui.Views.Containers, name: "containers", autoPosition: true},
 		{viewPtr: &gui.Views.Images, name: "images", autoPosition: true},
 		{viewPtr: &gui.Views.Volumes, name: "volumes", autoPosition: true},
+		{viewPtr: &gui.Views.Networks, name: "networks", autoPosition: true},
 
 		{viewPtr: &gui.Views.Main, name: "main", autoPosition: true},
 
@@ -127,6 +129,10 @@ func (gui *Gui) createAllViews() error {
 	gui.Views.Volumes.Title = gui.Tr.VolumesTitle
 	gui.Views.Volumes.SelBgColor = selectedLineBgColor
 
+	gui.Views.Networks.Highlight = true
+	gui.Views.Networks.Title = gui.Tr.NetworksTitle
+	gui.Views.Networks.SelBgColor = selectedLineBgColor
+
 	gui.Views.Options.Frame = false
 	gui.Views.Options.FgColor = gui.GetOptionsPanelTextColor()
 
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index 1532eeeac..eca2260b7 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -45,9 +45,11 @@ func dutchSet() TranslationSet {
 		ViewLogs:           "bekijk logs",
 		RemoveImage:        "verwijder image",
 		RemoveVolume:       "verwijder volume",
+		RemoveNetwork:      "verwijder network",
 		RemoveWithoutPrune: "verwijder zonder de ongelabeld ouders te verwijderen",
 		PruneContainers:    "vernietig bestaande containers",
 		PruneVolumes:       "vernietig ongebruikte volumes",
+		PruneNetworks:      "vernietig ongebruikte networks",
 		PruneImages:        "vernietig ongebruikte images",
 		ViewRestartOptions: "bekijk herstart opties",
 		RunCustomCommand:   "draai een vooraf bedacht aangepaste opdracht",
@@ -60,6 +62,7 @@ func dutchSet() TranslationSet {
 		StandaloneContainersTitle: "Alleenstaande Containers",
 		ImagesTitle:               "Images",
 		VolumesTitle:              "Volumes",
+		NetworksTitle:             "Networks",
 		CustomCommandTitle:        "Aangepast commando:",
 		ErrorTitle:                "Fout",
 		LogsTitle:                 "Logs",
@@ -78,6 +81,7 @@ func dutchSet() TranslationSet {
 		NoContainer:  "Geen container",
 		NoImages:     "Geen images",
 		NoVolumes:    "Geen volumes",
+		NoNetworks:   "Geen networks",
 
 		ConfirmQuit:                "Weet je zeker dat je weg wil gaan?",
 		MustForceToRemoveContainer: "Je kan geen draaiende container verwijderen tenzij je het forceert, Wil je het forceren?",
@@ -85,6 +89,7 @@ func dutchSet() TranslationSet {
 		ConfirmPruneImages:         "Weet je zeker dat je alle niet gebruikte images wil vernietigen?",
 		ConfirmPruneContainers:     "Weet je zeker dat je alle niet gestopte containers wil vernietigen?",
 		ConfirmPruneVolumes:        "Weet je zeker dat je alle niet gebruikte volumes wil vernietigen?",
+		ConfirmPruneNetworks:       "Weet je zeker dat je alle niet gebruikte networks wil vernietigen?",
 		StopService:                "Weet je zeker dat je deze service zijn containers wil stoppen?",
 		StopContainer:              "Weet je zeker dat je deze container wil stoppen?",
 		PressEnterToReturn:         "Druk op enter om terug te gaan naar lazydocker (Deze popup kan uit gezet worden door in de config dit neer te zetten `gui.returnImmediately: true`)",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 4d9aa1d27..b21b471fe 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -73,24 +73,29 @@ type TranslationSet struct {
 	TopTitle                    string
 	ImagesTitle                 string
 	VolumesTitle                string
+	NetworksTitle               string
 	NoContainers                string
 	NoContainer                 string
 	NoImages                    string
 	NoVolumes                   string
+	NoNetworks                  string
 	NoServices                  string
 	RemoveImage                 string
 	RemoveVolume                string
+	RemoveNetwork               string
 	RemoveWithoutPrune          string
 	RemoveWithoutPruneWithForce string
 	RemoveWithForce             string
 	PruneImages                 string
 	PruneContainers             string
 	PruneVolumes                string
+	PruneNetworks               string
 	ConfirmPruneContainers      string
 	ConfirmStopContainers       string
 	ConfirmRemoveContainers     string
 	ConfirmPruneImages          string
 	ConfirmPruneVolumes         string
+	ConfirmPruneNetworks        string
 	PruningStatus               string
 	StopService                 string
 	PressEnterToReturn          string
@@ -186,11 +191,13 @@ func englishSet() TranslationSet {
 		DownProject:                 "down project",
 		RemoveImage:                 "remove image",
 		RemoveVolume:                "remove volume",
+		RemoveNetwork:               "remove network",
 		RemoveWithoutPrune:          "remove without deleting untagged parents",
 		RemoveWithoutPruneWithForce: "remove (forced) without deleting untagged parents",
 		RemoveWithForce:             "remove (forced)",
 		PruneContainers:             "prune exited containers",
 		PruneVolumes:                "prune unused volumes",
+		PruneNetworks:               "prune unused networks",
 		PruneImages:                 "prune unused images",
 		StopAllContainers:           "stop all containers",
 		RemoveAllContainers:         "remove all containers (forced)",
@@ -210,6 +217,7 @@ func englishSet() TranslationSet {
 		StandaloneContainersTitle: "Standalone Containers",
 		ImagesTitle:               "Images",
 		VolumesTitle:              "Volumes",
+		NetworksTitle:             "Networks",
 		CustomCommandTitle:        "Custom Command:",
 		BulkCommandTitle:          "Bulk Command:",
 		ErrorTitle:                "Error",
@@ -230,6 +238,7 @@ func englishSet() TranslationSet {
 		NoContainer:  "No container",
 		NoImages:     "No images",
 		NoVolumes:    "No volumes",
+		NoNetworks:   "No networks",
 		NoServices:   "No services",
 
 		ConfirmQuit:                "Are you sure you want to quit?",
@@ -241,6 +250,7 @@ func englishSet() TranslationSet {
 		ConfirmStopContainers:      "Are you sure you want to stop all containers?",
 		ConfirmRemoveContainers:    "Are you sure you want to remove all containers?",
 		ConfirmPruneVolumes:        "Are you sure you want to prune all unused volumes?",
+		ConfirmPruneNetworks:       "Are you sure you want to prune all unused networks?",
 		StopService:                "Are you sure you want to stop this service's containers?",
 		StopContainer:              "Are you sure you want to stop this container?",
 		PressEnterToReturn:         "Press enter to return to lazydocker (this prompt can be disabled in your config by setting `gui.returnImmediately: true`)",
diff --git a/pkg/i18n/french.go b/pkg/i18n/french.go
index 1cd79a8a5..c2b826a69 100644
--- a/pkg/i18n/french.go
+++ b/pkg/i18n/french.go
@@ -53,11 +53,13 @@ func frenchSet() TranslationSet {
 		ViewLogs:                    "voir les enregistrements",
 		RemoveImage:                 "supprimer l'image",
 		RemoveVolume:                "supprimer le volume",
+		RemoveNetwork:               "supprimer le réseau",
 		RemoveWithoutPrune:          "supprimer sans effacer les parents non étiqueté",
 		RemoveWithoutPruneWithForce: "supprimer (forcer) sans effacer les parents non étiqueté",
 		RemoveWithForce:             "supprimer (forcer)",
 		PruneContainers:             "détruire les conteneurs arrêtes",
 		PruneVolumes:                "détruire les volumes non utilisés",
+		PruneNetworks:               "détruire les réseaux non utilisés",
 		PruneImages:                 "détruire les images non utilisés",
 		StopAllContainers:           "arrêter tous les conteneurs",
 		RemoveAllContainers:         "supprimer tous les conteneurs (forcer)",
@@ -76,6 +78,7 @@ func frenchSet() TranslationSet {
 		StandaloneContainersTitle: "Conteneurs Autonomes",
 		ImagesTitle:               "Images",
 		VolumesTitle:              "Volumes",
+		NetworksTitle:             "Réseaux",
 		CustomCommandTitle:        "Commande personalisé:",
 		BulkCommandTitle:          "Commande groupée:",
 		ErrorTitle:                "Erreur",
@@ -95,6 +98,7 @@ func frenchSet() TranslationSet {
 		NoContainer:  "Aucun conteneur",
 		NoImages:     "Aucune images",
 		NoVolumes:    "Aucun volumes",
+		NoNetworks:   "Aucun réseaux",
 
 		ConfirmQuit:                "Êtes vous certain de vouloir quitter?",
 		MustForceToRemoveContainer: "Vous ne pouvez pas supprimer un conteneur qui tourne sans le forcer. Voulez-vous le forcer ?",
@@ -104,6 +108,7 @@ func frenchSet() TranslationSet {
 		ConfirmStopContainers:      "Êtes-vous certain de vouloir arrêter tous les conteneurs ?",
 		ConfirmRemoveContainers:    "Êtes-vous certain de vouloir supprimer tous les conteneurs ?",
 		ConfirmPruneVolumes:        "Êtes-vous certain de vouloir détruire tous les volumes non utilisés ?",
+		ConfirmPruneNetworks:       "Êtes-vous certain de vouloir détruire tous les réseaux non utilisés ?",
 		StopService:                "Êtes-vous certain de vouloir arrêter le conteneur de ce service ?",
 		StopContainer:              "Êtes-vous certain de vouloir arrêter ce conteneur ?",
 		PressEnterToReturn:         "Appuiez sur Enter pour revenir à lazydocker (ce message peut être désactivé dans vos configurations en appliquant `gui.returnImmediately: true`)",
diff --git a/pkg/i18n/german.go b/pkg/i18n/german.go
index 4a205aa26..687e3eaa1 100644
--- a/pkg/i18n/german.go
+++ b/pkg/i18n/german.go
@@ -44,9 +44,11 @@ func germanSet() TranslationSet {
 		ViewLogs:           "zeige Protokolle",
 		RemoveImage:        "entferne Image",
 		RemoveVolume:       "entferne Volume",
+		RemoveNetwork:      "entferne Netzwerk",
 		RemoveWithoutPrune: "entfernen, ohne die unmarkierten Eltern zu entfernen",
 		PruneContainers:    "entferne verlassene Container",
 		PruneVolumes:       "entferne unbenutzte Volumes",
+		PruneNetworks:      "entferne unbenutzte Netzwerk",
 		PruneImages:        "entferne unbenutzte Images",
 		ViewRestartOptions: "zeige Neustartoptionen",
 		RunCustomCommand:   "führe vordefinierten benutzerdefinierten Befehl aus",
@@ -59,6 +61,7 @@ func germanSet() TranslationSet {
 		StandaloneContainersTitle: "Alleinstehende Container",
 		ImagesTitle:               "Images",
 		VolumesTitle:              "Volumes",
+		NetworksTitle:             "Netzwerk",
 		CustomCommandTitle:        "Benutzerdefinierter Befehl",
 		ErrorTitle:                "Fehler",
 		LogsTitle:                 "Protokoll",
@@ -77,6 +80,7 @@ func germanSet() TranslationSet {
 		NoContainer:  "Kein Container",
 		NoImages:     "Keine Images",
 		NoVolumes:    "Keine Volumes",
+		NoNetworks:   "Keine Netzwerk",
 
 		ConfirmQuit:                "Bist du dir sicher, dass du verlassen möchtest?",
 		MustForceToRemoveContainer: "Du kannst keinen Container entfernen, der noch ausgeführt wird außer du erzwingst es. Möchtest du es erzwingen?",
@@ -84,6 +88,7 @@ func germanSet() TranslationSet {
 		ConfirmPruneImages:         "Bist du dir sicher, dass du alle unbenutzten Images entfernen möchtest?",
 		ConfirmPruneContainers:     "Bist du dir sicher, dass du alle angehaltenen Container entfernen möchtes?",
 		ConfirmPruneVolumes:        "Bist du dir sicher, dass du alle unbenutzen Volumes entfernen möchtest?",
+		ConfirmPruneNetworks:       "Bist du dir sicher, dass du alle unbenutzen Netzwerk entfernen möchtest?",
 		StopService:                "Bist du dir sicher, dass du den Dienst dieses Containers anhalten möchtest?",
 		StopContainer:              "Bist du dir sicher, dass du den Container anhalten möchtest?",
 		PressEnterToReturn:         "Drücke Eingabe um zu lazydocker zurückzukehren. (Diese Nachfrage kann in Deiner Konfiguration deaktiviert werden, indem du folgenden Wert setzt: `gui.returnImmediately: true`)",
diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index 2cf12dd07..f35927456 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -44,9 +44,11 @@ func polishSet() TranslationSet {
 		ViewLogs:           "pokaż logi",
 		RemoveImage:        "usuń obraz",
 		RemoveVolume:       "usuń wolumen",
+		RemoveNetwork:      "usuń seici",
 		RemoveWithoutPrune: "usuń bez kasowania nieoznaczonych rodziców",
 		PruneContainers:    "wyczyść kontenery",
 		PruneVolumes:       "wyczyść nieużywane wolumeny",
+		PruneNetworks:      "wyczyść nieużywane sieci",
 		PruneImages:        "wyczyść nieużywane obrazy",
 		ViewRestartOptions: "pokaż opcje restartu",
 		RunCustomCommand:   "wykonaj predefiniowaną własną komende",
@@ -59,6 +61,7 @@ func polishSet() TranslationSet {
 		StandaloneContainersTitle: "Kontenery samodzielne",
 		ImagesTitle:               "Obrazy",
 		VolumesTitle:              "Wolumeny",
+		NetworksTitle:             "Seici",
 		CustomCommandTitle:        "Własna komenda:",
 		ErrorTitle:                "Błąd",
 		LogsTitle:                 "Logi",
@@ -77,6 +80,7 @@ func polishSet() TranslationSet {
 		NoContainer:  "Brak kontenera",
 		NoImages:     "Brak obrazów",
 		NoVolumes:    "Brak wolumenów",
+		NoNetworks:   "Brak sieci",
 
 		ConfirmQuit:                "Na pewno chcesz wyjść?",
 		MustForceToRemoveContainer: "Nie możesz usunąć uruchomionego kontenera dopóki nie zrobisz tego siłą. Chcesz wykonać to z siłą?",
@@ -84,6 +88,7 @@ func polishSet() TranslationSet {
 		ConfirmPruneImages:         "Na pewno wyczyścić wszystkie nieużywane obrazy?",
 		ConfirmPruneContainers:     "Na pewno wyczyścić wszystkie nieuruchomione kontenery?",
 		ConfirmPruneVolumes:        "Na pewno wyczyścić wszystkie nieużywane wolumeny?",
+		ConfirmPruneNetworks:       "Na pewno wyczyścić wszystkie nieużywane seici?",
 		StopService:                "Na pewno zatrzymać kontenery tego serwisu?",
 		StopContainer:              "Na pewno zatrzymać ten kontener?",
 		PressEnterToReturn:         "Wciśnij enter aby powrócić do lazydockera (ten komunikat może być wyłączony w konfiguracji poprzez ustawienie `gui.returnImmediately: true`)",
diff --git a/pkg/i18n/turkish.go b/pkg/i18n/turkish.go
index 4a378b7a6..1e1bf47d2 100644
--- a/pkg/i18n/turkish.go
+++ b/pkg/i18n/turkish.go
@@ -44,9 +44,11 @@ func turkishSet() TranslationSet {
 		ViewLogs:           "kayıt defterini görüntüle",
 		RemoveImage:        "imajı kaldır",
 		RemoveVolume:       "alanı kaldır",
+		RemoveNetwork:      "ağı kaldır",
 		RemoveWithoutPrune: "etkisiz ebeveynleri silmeden kaldır",
 		PruneContainers:    "çalışmayan konteynerleri temizle",
 		PruneVolumes:       "kullanılmayan alanları temizle",
+		PruneNetworks:      "kullanılmayan ağları temizle",
 		PruneImages:        "kullanılmayan imajları temizle",
 		ViewRestartOptions: "yeniden başlatma seçeneklerini görüntüle",
 		RunCustomCommand:   "önceden tanımlanmış özel komutu çalıştır",
@@ -59,6 +61,7 @@ func turkishSet() TranslationSet {
 		StandaloneContainersTitle: "Bağımsız Konteynerler",
 		ImagesTitle:               "Imajlar",
 		VolumesTitle:              "Alanlar",
+		NetworksTitle:             "Ağları",
 		CustomCommandTitle:        "Özel Komut:",
 		ErrorTitle:                "Hata",
 		LogsTitle:                 "Kayitlar",
@@ -77,6 +80,7 @@ func turkishSet() TranslationSet {
 		NoContainer:  "Konteyner yok",
 		NoImages:     "Imajlar yok",
 		NoVolumes:    "Alanlar yok",
+		NoNetworks:   "Ağları yok",
 
 		ConfirmQuit:                "Çıkmak istediğine emin misin?",
 		MustForceToRemoveContainer: "Zorlamadan çalışan bir konteyneri kaldıramazsınız. Zorlamak ister misin?",
@@ -84,6 +88,7 @@ func turkishSet() TranslationSet {
 		ConfirmPruneImages:         "Kullanılmayan tüm görüntüleri temizlemek istediğinize emin misiniz?",
 		ConfirmPruneContainers:     "Durdurulan tüm konteynerları temizlemek istediğinizden emin misiniz?",
 		ConfirmPruneVolumes:        "Kullanılmayan tüm alanları temizlemek istediğinizden emin misiniz?",
+		ConfirmPruneNetworks:       "Kullanılmayan tüm ağları temizlemek istediğinizden emin misiniz?",
 		StopService:                "Bu servisin konteynerlerini durdurmak istediğinize emin misiniz?",
 		StopContainer:              "Bu konteyneri durdurmak istediğinize emin misiniz?",
 		PressEnterToReturn:         "lazydocker' a geri dönmek için enter tuşuna basın ( Bu uyarı, `gui.return Immediately: true` ayarıyla devre dışı bırakılabilir)",