feat: modernize dashboard widgets

This commit is contained in:
Thomas Camlong authored and ajnart committed 2026-08-13 19:54:28 +02:00
1 parent 1a5e083fd0
commit 6f2cd7fc2b
270 files changed
+10189 -3544

No files matched your search

+528 -31
View File
@@ -741,7 +741,7 @@
},
"create": {
"title": "Create Custom Widget",
"subtitle": "Build a safe JSX widget with inline API sources, options, queries, and actions."
"subtitle": "Define an API URL, authentication, and how to display the response data."
},
"edit": {
"title": "Edit Custom Widget"
@@ -766,12 +766,62 @@
"migrate": "Migrate Custom Widget",
"copyMigrationPrompt": "Copy LLM migration prompt",
"pasteMigration": "Paste migrated widget",
"importMigration": "Import migrated JSON file"
"importMigration": "Import migrated JSON file",
"addMapping": "Add Mapping",
"addColumn": "Add Column",
"removeMapping": "Remove mapping",
"removeColumn": "Remove column",
"addItem": "Add Item",
"removeItem": "Remove item",
"addBar": "Add Bar"
},
"field": {
"name": "Name",
"description": "Description",
"iconUrl": "Icon URL"
"iconUrl": "Icon URL",
"url": "URL",
"authType": "Auth Type",
"headerName": "Header/Query Parameter Name",
"method": "Method",
"requestBody": "Request Body",
"displayType": "Display Type",
"jsonPath": "JSON Path",
"jsonPathHint": "Use JSONPath syntax to extract values, e.g. $.data.temperature or $.items[0].name",
"label": "Label",
"unit": "Unit",
"mappings": "Mappings",
"tablePath": "Array JSON Path",
"tablePathHint": "Path to the array in the response, e.g. $.data.items",
"columns": "Columns",
"header": "Header",
"items": "Items",
"gridColumns": "Grid Columns",
"cardStyle": "Card Style",
"bars": "Bars",
"valuePath": "Value JSON Path",
"maxPath": "Max Value JSON Path",
"showPercentage": "Show Percentage",
"barSize": "Bar Size",
"goodValues": "Good Values (comma-separated)",
"dotSize": "Dot Size",
"valueSize": "Value Size",
"labelPosition": "Label Position",
"kvLayout": "Layout",
"striped": "Striped Rows",
"compact": "Compact Mode",
"maxHeight": "Max Height (px)",
"color": "Color",
"buttonLabel": "Button Label",
"buttonColor": "Button Color",
"confirmText": "Confirmation Text",
"confirmTextHint": "If set, a confirmation dialog will appear before executing the request",
"successMessage": "Success Message",
"successMessageHint": "Message shown after successful execution",
"enabled": "Enabled",
"template": {
"label": "JSX Template",
"description": "Mantine JSX template. Access API response fields via data bindings (e.g. data.name). Use whitelisted components only. Forbidden: constructor, __proto__, eval, Function, window, document."
}
},
"editor": {
"errorBoundary": {
@@ -1026,9 +1076,9 @@
"journal": "Redacted request journal",
"actionParameters": "Action parameters (JSON)",
"invalidParameters": "Use the declared string, number, and boolean parameter types.",
"runDestructive": "Run destructive action",
"runAction": "Run action",
"deleteConfirmation": "This preview action sends a DELETE request to the configured API.",
"runDestructive": "Run destructive action",
"runAction": "Run action",
"deleteConfirmation": "This preview action sends a DELETE request to the configured API.",
"simulated": "Action simulated",
"httpStatus": "HTTP {status, number}",
"tab": {
@@ -1059,7 +1109,11 @@
"modify": "Modify",
"full": "Full"
}
}
},
"title": "Preview",
"test": "Test",
"hint": "Click Test to preview the API response with your current configuration.",
"rawResponse": "Raw JSON response"
},
"notification": {
"created": "Widget \"{name}\" created successfully.",
@@ -1072,15 +1126,21 @@
"migrationPromptCopyError": "Failed to copy the migration prompt.",
"aiPromptCopied": "AI prompt copied to clipboard",
"aiPromptCopiedWithCount": "AI prompt copied to clipboard ({count, number} characters).",
"aiPromptCopyError": "Failed to copy the prompt to the clipboard.",
"aiPromptCopyError": "Failed to copy prompt to clipboard. Your browser may not support this feature.",
"updateError": "Failed to update widget. Your changes were not saved.",
"importError": "Failed to import widget. Ensure the file uses the homarr-custom-widget-v2 schema.",
"importError": "Failed to import widget. Ensure the file is a valid custom widget JSON export.",
"exportError": "Failed to export widget.",
"duplicated": "Widget \"{name}\" duplicated.",
"duplicateError": "Failed to duplicate widget.",
"toggleError": "Failed to toggle widget status.",
"deleteError": "Failed to delete widget.",
"previewError": "Failed to create the preview. Check the API source and try again."
"previewError": "Failed to fetch preview. Check the URL and try again.",
"aiPromptDescription": "Copy a pre-built prompt to paste into any AI chatbot (ChatGPT, Claude, Gemini...). It includes the full widget schema and your API response so the AI can generate a ready-to-import JSON config for you.",
"aiPromptCopy": "Copy to clipboard",
"aiPromptNoResponse": "Tip: Run a test first to include your API response in the prompt for better results.",
"createError": "Failed to create widget. Check your API endpoint is reachable.",
"executed": "Action executed successfully.",
"executeError": "Action failed: {error}"
},
"importReview": {
"title": "Review custom widget import",
@@ -1122,6 +1182,91 @@
"cancel": "Cancel import",
"confirm": "Import widget",
"confirmMigration": "Confirm v2 replacement"
},
"placeholder": {
"exampleLabel": "CPU Temperature",
"exampleLabelShort": "CPU Temp",
"exampleHeader": "Name",
"exampleUnit": "°C",
"iconUrl": "https://...",
"url": "https://api.example.com/api/v1/status",
"headerName": "X-API-Key",
"jsonPath": "$.data.value",
"tablePath": "$.data.items",
"columnJsonPath": "$.name",
"valuePath": "$.data.used",
"maxPath": "$.data.total",
"goodValues": "online, true, up",
"color": "blue"
},
"cardStyleOption": {
"filled": "Filled",
"outline": "Outline",
"subtle": "Subtle"
},
"layoutOption": {
"list": "List",
"grid": "Grid"
},
"sizeOption": {
"sm": "Small",
"md": "Medium",
"lg": "Large",
"xl": "Extra Large"
},
"labelPositionOption": {
"above": "Above",
"below": "Below"
},
"fieldset": {
"general": "General",
"connection": "API Connection",
"display": "Display Configuration"
},
"displayTypeDescription": {
"singleValue": "Show one extracted value with a label and unit",
"keyValue": "Show multiple labeled values side by side",
"table": "Show rows of data in a table format",
"statGrid": "Colored stat cards in a grid — like Pi-Hole or Speedtest widgets",
"progressBars": "Progress bars showing usage or completion — for disk, memory, quotas",
"statusIndicator": "Colored status dots showing online/offline or health states",
"countGrid": "Compact number + label counters in a tight grid",
"raw": "Pretty-printed JSON output for debugging",
"actionButton": "A button that triggers a request when clicked",
"customJsx": "Custom JSX layout using whitelisted Mantine components with full API data binding"
},
"authType": {
"none": "None",
"bearer": "Bearer Token",
"basic": "Basic Auth",
"apiKeyHeader": "API Key (Header)",
"apiKeyQuery": "API Key (Query)"
},
"displayType": {
"singleValue": "Single Value",
"keyValue": "Key-Value",
"table": "Table",
"statGrid": "Stat Grid",
"progressBars": "Progress Bars",
"statusIndicator": "Status Indicator",
"countGrid": "Count Grid",
"raw": "Raw JSON",
"actionButton": "Action Button",
"customJsx": "Custom JSX"
},
"secret": {
"apiKey": "API Key / Token",
"username": "Username",
"password": "Password",
"savedPlaceholder": "••••••• (saved, leave empty to keep)"
},
"table": {
"name": "Name",
"url": "URL",
"display": "Display"
},
"widget": {
"disabled": "This widget is disabled"
}
},
"workshop": {
@@ -1325,7 +1470,8 @@
"analytics": "Analytics",
"vpn": "VPN",
"mediaLibrary": "Media Library",
"uptimeMonitoring": "Uptime Monitoring"
"uptimeMonitoring": "Uptime Monitoring",
"beszel": "Beszel"
},
"testConnection": {
"action": {
@@ -1858,7 +2004,13 @@
"kilometersPerHour": "km/h",
"milesPerHour": "mph"
}
}
},
"widgetQuery": {
"loading": "Loading widget data",
"stale": "Could not refresh {widget}; showing saved data"
},
"total": "Total",
"filesystemUsage": "{count, plural, one {Show usage for # filesystem} other {Show usage for # filesystems}}"
},
"section": {
"option": {
@@ -1906,6 +2058,67 @@
"title": "Remove container",
"message": "Remove this container? Its contents will move into the surrounding area."
}
},
"dynamic": {
"action": {
"create": "New dynamic section",
"remove": "Remove dynamic section"
},
"option": {
"title": {
"label": "Title"
},
"customCssClasses": {
"label": "Custom css classes"
},
"borderColor": {
"label": "Border color"
}
},
"remove": {
"title": "Remove dynamic section",
"message": "Are you sure you want to remove this dynamic section? Items will be moved at the same location in the parent section."
}
},
"category": {
"field": {
"name": {
"label": "Name"
}
},
"action": {
"create": "New category",
"edit": "Rename category",
"remove": "Remove category",
"moveUp": "Move up",
"moveDown": "Move down",
"createAbove": "New category above",
"createBelow": "New category below",
"openAllInNewTabs": "Open all in tabs"
},
"create": {
"title": "New category",
"submit": "Add category"
},
"remove": {
"title": "Remove category",
"message": "Are you sure you want to remove the category {name}?"
},
"edit": {
"title": "Rename category",
"submit": "Rename category"
},
"menu": {
"label": {
"create": "New category",
"changePosition": "Change position",
"settings": "Settings"
}
},
"openAllInNewTabs": {
"title": "Open all in tabs",
"text": "Some browsers may block the bulk-opening of tabs for security reasons. Homarr was unable to open all windows, because your browser blocked this action. Please allow \"Open pop-up windows\" and re-try."
}
}
},
"item": {
@@ -1930,12 +2143,25 @@
"error": "Error",
"loading": "Loading",
"idle": "Idle"
},
"notification": {
"saveError": {
"title": "Unable to save widget",
"message": "The widget changes were rolled back"
}
}
},
"create": {
"title": "Choose item to add",
"search": "Filter items",
"addToBoard": "Add to board"
"addToBoard": "Add to board",
"addAtPosition": "Add item here",
"notification": {
"error": {
"title": "Unable to add item",
"message": "The item could not be added to this board"
}
}
},
"moveResize": {
"title": "Move / resize item",
@@ -1999,6 +2225,11 @@
"remove": {
"title": "Remove item",
"message": "Are you sure you want to remove this item?"
},
"advancedFocus": {
"open": "Open advanced view",
"close": "Close advanced view",
"label": "{widget} advanced view"
}
},
"widget": {
@@ -2103,6 +2334,32 @@
"showBroadcastMessage": {
"label": "Show broadcast messages"
}
},
"noProjectSelected": "No project selected",
"runnerStatus": "Runner: {status}",
"updatedAt": "Updated {date}",
"projectId": "Project: {id}",
"sessionReceived": "Session received: {value}",
"sessionSent": "Session sent: {value}",
"sessionId": "Session: {id}",
"startedAt": "Started {date}",
"emptyItems": "No active or recent jobs in this snapshot",
"metric": {
"running": "Running",
"completed": "Done",
"failed": "Failed",
"canceled": "Canceled",
"download": "Download",
"upload": "Upload"
},
"status": {
"running": "Running",
"completed": "Completed",
"failed": "Failed",
"canceled": "Canceled",
"stopped": "Stopped",
"idle": "Idle",
"unknown": "Unknown"
}
},
"wud": {
@@ -2169,7 +2426,12 @@
"dnsQueriesToday": "Queries today",
"domainsBeingBlocked": "Domains on blocklist"
},
"domainsTooltip": "Due to multiple integrations Homarr can't calculate the exact number of domains being blocked"
"domainsTooltip": "Due to multiple integrations Homarr can't calculate the exact number of domains being blocked",
"status": {
"enabled": "Enabled",
"disabled": "Disabled",
"unknown": "Unknown"
}
},
"dnsHoleControls": {
"name": "DNS Hole Controls",
@@ -2194,7 +2456,8 @@
}
},
"error": {
"internalServerError": "Failed to control DNS Hole"
"internalServerError": "Failed to control DNS Hole",
"bulkActionsFailed": "{count, plural, one {# action failed} other {# actions failed}}"
},
"controls": {
"enableAll": "Enable All",
@@ -2288,11 +2551,20 @@
"noStation": "No station selected",
"option": {
"baseUrl": {
"label": "Search.ch URL"
"label": "Search.ch URL",
"description": "Custom URLs must resolve to a public IP address. Private and local hosts are rejected."
},
"station": {
"label": "Station"
}
},
"error": {
"customSourceUnavailable": "The timetable source is unavailable. Check that its URL resolves to a public IP address.",
"stationSearch": "Unable to search stations. Check the custom URL and your board access."
},
"warning": {
"stale": "The timetable could not be refreshed. Showing departures last updated at {time}.",
"staleCompact": "Stale data"
}
},
"notebook": {
@@ -2365,7 +2637,9 @@
"discard": "Discard changes",
"keepEditing": "Keep editing"
}
}
},
"saveFailed": "Unable to save note",
"documentStats": "{words, plural, one {# word} other {# words}} · {characters, plural, one {# character} other {# characters}}"
},
"anchorNote": {
"name": "Anchor Note",
@@ -2393,7 +2667,17 @@
"cancel": "Cancel",
"readOnlyViewer": "You have viewer access to this note. Editing is disabled.",
"saveForbidden": "You do not have permission to edit this note.",
"saveFailed": "Failed to save this note. Please try again."
"saveFailed": "Failed to save this note. Please try again.",
"createdAt": "Created {date}",
"permission": {
"owner": "Owner",
"editor": "Editor",
"viewer": "Viewer"
},
"status": {
"pinned": "Pinned",
"archived": "Archived"
}
},
"iframe": {
"name": "iFrame",
@@ -2452,6 +2736,26 @@
"clickable": {
"label": "Clickable"
}
},
"state": {
"on": "On",
"off": "Off",
"unavailable": "Unavailable",
"unknown": "Unknown"
},
"advanced": {
"entityId": "Entity ID: {id}",
"lastChanged": "Changed {date}",
"lastUpdated": "Updated {date}",
"attribute": {
"unit": "Unit",
"deviceClass": "Device class",
"icon": "Icon"
}
},
"error": {
"loadFailed": "Unable to load entity",
"toggleFailed": "Unable to update entity"
}
},
"smartHome-executeAutomation": {
@@ -2467,11 +2771,32 @@
},
"spotlightAction": {
"run": "Run {name}"
},
"advanced": {
"lastExecuted": "Last run at {time}",
"automationId": "Automation ID: {id}",
"ready": "Ready to run",
"noPermission": "No permission to run this automation"
},
"status": {
"running": "Running automation",
"success": "Automation completed"
},
"error": {
"executeFailed": "Unable to run automation"
}
},
"stockPrice": {
"name": "Stock Price",
"description": "Displays the current stock price of a company",
"advanced": {
"currentPrice": "Current price",
"previousClose": "Previous close",
"change": "Change",
"changePercentage": "Change (%)",
"minimum": "Minimum",
"maximum": "Maximum"
},
"option": {
"stock": {
"label": "Stock symbol"
@@ -2569,6 +2894,13 @@
"showUnmonitored": {
"label": "Show unmonitored"
}
},
"advanced": {
"previousMonth": "Show previous month",
"nextMonth": "Show next month",
"eventCount": "{count, plural, one {# event} other {# events}}",
"loading": "Loading calendar events...",
"noEvents": "No events in this month"
}
},
"weather": {
@@ -2629,6 +2961,18 @@
"thunderstorm": "Thunderstorm",
"thunderstormWithHail": "Thunderstorm with hail",
"unknown": "Unknown"
},
"details": "Show weather details",
"detailsFor": "Show weather details for {date}",
"advanced": {
"forecast": "7-day forecast",
"day": "Day",
"conditions": "Conditions",
"temperature": "High / low",
"humidity": "Humidity",
"wind": "Wind / gusts ({unit})",
"sun": "Sunrise / sunset",
"noForecast": "No forecast data available"
}
},
"indexerManager": {
@@ -2641,6 +2985,11 @@
},
"title": "Indexer manager",
"testAll": "Test all",
"status": {
"healthy": "Healthy",
"unhealthy": "Unhealthy",
"disabled": "Disabled"
},
"error": {
"internalServerError": "Failed to fetch indexers status"
}
@@ -2698,7 +3047,10 @@
"minutes": "{count} minutes",
"used": "Used",
"available": "Available",
"lastSeen": "Last status update: {lastSeen}"
"lastSeen": "Last status update: {lastSeen}",
"updatesAvailable": "{count, plural, one {# update available} other {# updates available}}",
"rebootRequired": "Reboot required",
"rebootNotRequired": "No reboot required"
},
"memory": {},
"error": {
@@ -2816,17 +3168,50 @@
"internalServerError": "Failed to fetch Coolify data"
},
"server": {
"buildServer": "Build"
"buildServer": "Build",
"resourceCounts": "{applications, plural, one {# app} other {# apps}} / {services, plural, one {# service} other {# services}}",
"reachability": "Reachability",
"usability": "Usability"
},
"source": {
"url": "Source: {url}",
"unavailable": "{source}: unavailable"
},
"instances": {
"title": "Instances"
},
"action": {
"openResource": "Open {name}",
"openLogs": "Open {name} logs",
"showIp": "Show IP address",
"hideIp": "Hide IP address"
},
"status": {
"running": "Running",
"stopped": "Stopped",
"exited": "Exited",
"starting": "Starting",
"restarting": "Restarting",
"unknown": "Unknown",
"online": "Online",
"offline": "Offline",
"reachable": "Reachable",
"unreachable": "Unreachable",
"usable": "Usable",
"unusable": "Unusable"
}
},
"vpn": {
"name": "VPN",
"description": "Overview of your VPN connections",
"serviceUnavailable": "VPN unavailable",
"option": {}
"option": {},
"status": {
"running": "Running",
"notRunning": "Not running",
"unavailable": "Unavailable",
"vpn": "VPN: {status}"
}
},
"ups": {
"name": "UPS",
@@ -2853,7 +3238,13 @@
"runtime": "Runtime",
"load": "Load",
"input": "Input",
"output": "Output"
"output": "Output",
"batteryVoltage": "Battery voltage",
"power": "Power",
"temperature": "Temperature",
"manufacturer": "Manufacturer",
"model": "Model",
"serial": "Serial"
},
"error": {
"internalServerError": "Failed to fetch UPS data"
@@ -3124,7 +3515,13 @@
"resolution": "Resolution",
"target": "Target codec"
}
}
},
"unknownUser": "Unknown user"
},
"summary": {
"sessions": "{count, plural, one {# session} other {# sessions}}",
"playing": "{count} playing",
"transcoding": "{count} transcoding"
}
},
"paperlessNgx": {
@@ -3337,6 +3734,9 @@
"movies": "Missing Movies",
"providers": "Provider Issues",
"status": "Health Issues",
"sonarrSignalr": "Sonarr SignalR",
"radarrSignalr": "Radarr SignalR",
"announcements": "Announcements",
"option": {
"showMissingEpisodes": {
"label": "Show missing episodes",
@@ -3383,7 +3783,8 @@
"users": "Users",
"photos": "Photos",
"videos": "Videos",
"storage": "Used Storage"
"storage": "Used Storage",
"albumLimit": "Largest albums (up to {count} shown)"
},
"immich-albumCarousel": {
"name": "Immich Album",
@@ -3407,7 +3808,16 @@
}
},
"description": "Slideshow of pictures from an Immich album or your full library",
"noPhotos": "No photos found"
"noPhotos": "No photos found",
"albumPhoto": "Album photo",
"actions": {
"previousPhoto": "Previous photo",
"nextPhoto": "Next photo",
"pauseSlideshow": "Pause slideshow",
"resumeSlideshow": "Resume slideshow",
"toggleSlideshow": "Pause or resume slideshow",
"photo": "Photo {number}"
}
},
"downloads": {
"name": "Download Client",
@@ -3782,6 +4192,13 @@
"showPosterImage": {
"label": "Show poster image"
}
},
"error": {
"allFeedsFailed": "Unable to load RSS feeds. Check the feed URLs and try again."
},
"warning": {
"partial": "{count, plural, one {# RSS feed could not be loaded} other {# RSS feeds could not be loaded}}",
"stale": "RSS feeds could not be refreshed. Showing previously loaded entries."
}
},
"releases": {
@@ -3912,14 +4329,31 @@
"noProviderResponse": "No response from provider",
"unexpected": "Unexpected provider error"
}
}
},
"expandDetails": "Show details for {name}",
"collapseDetails": "Hide details for {name}"
},
"networkControllerSummary": {
"option": {},
"advanced": {
"updated": "Updated",
"metric": {
"latency": "Latency",
"ping": "Ping",
"uptime": "Uptime",
"users": "Users",
"guests": "Guests"
}
},
"card": {
"vpn": {
"countConnected": "{count} connected"
}
"countConnected": "{count, plural, one {# connected} other {# connected}}",
"label": "VPN"
},
"wan": "WAN",
"web": "Web",
"wifi": "Wi-Fi",
"lan": "LAN"
},
"error": {
"integrationsDisconnected": "No data available, all integrations disconnected",
@@ -3929,6 +4363,9 @@
"description": "Displays the summary of a Network Controller (like UniFi Controller)"
},
"networkControllerStatus": {
"advanced": {
"updatedAt": "Updated {date}"
},
"card": {
"variants": {
"wired": {
@@ -3997,6 +4434,16 @@
"recv": "Received",
"title": "Network Interfaces"
}
},
"empty": {
"noInterfaces": "No network interface data yet"
},
"versionUnknown": "Unknown version",
"metricAccessible": "{metric}: {value}%, {status}",
"status": {
"normal": "Normal",
"warning": "Warning",
"critical": "Critical"
}
},
"notifications": {
@@ -4046,6 +4493,12 @@
"noSectionsEnabled": "Enable at least one section in widget options.",
"error": {
"internalServerError": "Failed to fetch speedtest data"
},
"range": {
"twelveHours": "12h",
"oneDay": "24h",
"all": "All",
"lastThirty": "Last 30"
}
},
"uptimeKuma": {
@@ -4086,6 +4539,11 @@
},
"error": {
"internalServerError": "Failed to fetch uptime data"
},
"status": {
"up": "Up",
"down": "Down",
"paused": "Paused"
}
},
"traefik": {
@@ -4120,7 +4578,20 @@
},
"error": {
"internalServerError": "Failed to fetch Traefik data"
}
},
"resourceType": {
"router": "Router",
"service": "Service",
"middleware": "Middleware"
},
"resourceStatus": {
"enabled": "Enabled",
"disabled": "Disabled",
"warning": "Warning",
"error": "Error",
"unknown": "Unknown"
},
"failedEndpoint": "Failed: {endpoint}"
},
"audioStats": {
"name": "Audio stats",
@@ -4242,7 +4713,9 @@
}
},
"status": {
"unhealthy": "Unhealthy"
"unhealthy": "Unhealthy",
"smart": "SMART",
"free": "{percentage}% free"
}
},
"customApi": {
@@ -4363,6 +4836,12 @@
},
"column": {
"system": "System",
"source": "Source",
"hostname": "Hostname",
"os": "OS",
"cpuModel": "CPU model",
"cores": "Cores",
"memoryTotal": "Memory total",
"cpu": "CPU",
"memory": "Memory",
"disk": "Disk",
@@ -4423,6 +4902,14 @@
"empty": {
"noSystems": "No systems found"
},
"metadata": {
"hostname": "Hostname",
"os": "OS",
"cpuModel": "CPU model",
"cores": "Cores",
"memoryTotal": "Memory total",
"source": "Source"
},
"metric": {
"cpu": "CPU",
"memory": "Memory",
@@ -4503,7 +4990,9 @@
"internalServerError": "Unable to connect to Beszel. Check your integration settings.",
"liveConnectionFailed": "Live connection failed. Your Beszel instance may not support real-time streaming.",
"switchToHistorical": "Switch to historical view",
"systemNotFound": "Selected system was not found. Choose a different system."
"systemNotFound": "Selected system was not found. Choose a different system.",
"selectionSaveTitle": "Unable to save selection",
"selectionSaveMessage": "Your system or time period selection could not be saved. Please try again."
},
"chart": {
"cpu": {
@@ -4551,6 +5040,14 @@
"title": "Docker Network I/O",
"subtitle": "Network traffic of docker containers"
}
},
"period": {
"live": "Live",
"oneHour": "1h",
"twelveHours": "12h",
"oneDay": "24h",
"oneWeek": "1w",
"thirtyDays": "30d"
}
}
},