${tzBadge}
${total !== null ? html`
${t('common.total', { count: total })}` : nothing}
diff --git a/src/meshcore_hub/web/static/locales/en.json b/src/meshcore_hub/web/static/locales/en.json
index 7a3bdfe..e9d3dec 100644
--- a/src/meshcore_hub/web/static/locales/en.json
+++ b/src/meshcore_hub/web/static/locales/en.json
@@ -1,4 +1,21 @@
{
+ "entities": {
+ "home": "Home",
+ "dashboard": "Dashboard",
+ "nodes": "Nodes",
+ "node": "Node",
+ "node_detail": "Node Detail",
+ "advertisements": "Advertisements",
+ "advertisement": "Advertisement",
+ "messages": "Messages",
+ "message": "Message",
+ "map": "Map",
+ "members": "Members",
+ "member": "Member",
+ "admin": "Admin",
+ "tags": "Tags",
+ "tag": "Tag"
+ },
"nav": {
"home": "Home",
"dashboard": "Dashboard",
@@ -9,18 +26,6 @@
"members": "Members",
"admin": "Admin"
},
- "page_title": {
- "dashboard": "Dashboard - {{network_name}}",
- "nodes": "Nodes - {{network_name}}",
- "node_detail": "Node Detail - {{network_name}}",
- "advertisements": "Advertisements - {{network_name}}",
- "messages": "Messages - {{network_name}}",
- "map": "Map - {{network_name}}",
- "members": "Members - {{network_name}}",
- "admin": "Admin - {{network_name}}",
- "admin_node_tags": "Node Tags - Admin - {{network_name}}",
- "admin_members": "Members - Admin - {{network_name}}"
- },
"common": {
"filter": "Filter",
"clear": "Clear",
@@ -30,7 +35,17 @@
"delete": "Delete",
"edit": "Edit",
"move": "Move",
+ "save": "Save",
"save_changes": "Save Changes",
+ "add": "Add",
+ "add_entity": "Add {{entity}}",
+ "add_new_entity": "Add New {{entity}}",
+ "edit_entity": "Edit {{entity}}",
+ "delete_entity": "Delete {{entity}}",
+ "delete_all_entity": "Delete All {{entity}}",
+ "move_entity": "Move {{entity}}",
+ "copy_entity": "Copy {{entity}}",
+ "view_entity": "View {{entity}}",
"previous": "Previous",
"next": "Next",
"go_home": "Go Home",
@@ -39,12 +54,12 @@
"failed_to_load_page": "Failed to load page",
"total": "{{count}} total",
"shown": "{{count}} shown",
+ "count_entity": "{{count}} {{entity}}",
"type": "Type",
"name": "Name",
"key": "Key",
"value": "Value",
"time": "Time",
- "node": "Node",
"actions": "Actions",
"updated": "Updated",
"sign_in": "Sign In",
@@ -53,7 +68,6 @@
"all_types": "All Types",
"all_nodes": "All Nodes",
"all_members": "All Members",
- "member": "Member",
"node_type": "Node Type",
"show": "Show",
"search_placeholder": "Search by name, ID, or public key...",
@@ -70,11 +84,17 @@
"received_by": "Received By",
"receivers": "Receivers",
"from": "From",
- "message": "Message",
"close": "close",
"unnamed": "Unnamed",
"unnamed_node": "Unnamed Node"
},
+ "links": {
+ "website": "Website",
+ "github": "GitHub",
+ "discord": "Discord",
+ "youtube": "YouTube",
+ "profile": "Profile"
+ },
"time": {
"days_ago": "{{count}}d ago",
"hours_ago": "{{count}}h ago",
@@ -95,15 +115,10 @@
"welcome_default": "Welcome to the {{network_name}} mesh network dashboard. Monitor network activity, view connected nodes, and explore message history.",
"total_nodes": "Total Nodes",
"all_discovered_nodes": "All discovered nodes",
- "advertisements": "Advertisements",
- "messages": "Messages",
"network_info": "Network Info",
"network_activity": "Network Activity",
"meshcore_attribution": "Our local off-grid mesh network is made possible by",
"meshcore_tagline": "Connecting people and things, without using the internet",
- "website": "Website",
- "github": "GitHub",
- "profile": "Profile",
"frequency": "Frequency",
"bandwidth": "Bandwidth",
"spreading_factor": "Spreading Factor",
@@ -111,35 +126,28 @@
"tx_power": "TX Power"
},
"dashboard": {
- "title": "Dashboard",
"total_nodes": "Total Nodes",
"all_discovered_nodes": "All discovered nodes",
- "advertisements": "Advertisements",
- "messages": "Messages",
"recent_advertisements": "Recent Advertisements",
"recent_channel_messages": "Recent Channel Messages",
"channel": "Channel {{number}}",
"no_advertisements_yet": "No advertisements recorded yet."
},
"nodes": {
- "title": "Nodes",
"no_nodes_found": "No nodes found.",
"node_not_found": "Node not found: {{public_key}}",
"back_to_nodes": "Back to Nodes",
"scan_to_add": "Scan to add as contact",
"recent_advertisements": "Recent Advertisements",
"no_advertisements": "No advertisements recorded.",
- "tags": "Tags",
"no_tags": "No tags defined.",
"edit_tags": "Edit Tags",
"add_tags": "Add Tags"
},
"advertisements": {
- "title": "Advertisements",
"no_advertisements_found": "No advertisements found."
},
"messages": {
- "title": "Messages",
"no_messages_found": "No messages found.",
"type_direct": "Direct",
"type_channel": "Channel",
@@ -147,7 +155,6 @@
"type_public": "Public"
},
"map": {
- "title": "Map",
"show_labels": "Show Labels",
"infrastructure_only": "Infrastructure Only",
"legend": "Legend:",
@@ -162,8 +169,6 @@
"select_destination_node": "-- Select destination node --"
},
"members": {
- "title": "Members",
- "count": "{{count}} members",
"no_members_configured": "No members configured",
"no_members_description": "To display network members, create a members.yaml file in your seed directory.",
"members_file_format": "Members File Format",
@@ -180,78 +185,56 @@
"failed_to_load": "Failed to load page"
},
"admin": {
- "title": "Admin",
"access_denied": "Access Denied",
"admin_not_enabled": "The admin interface is not enabled.",
"admin_enable_hint": "Set
WEB_ADMIN_ENABLED=true to enable admin features.",
"auth_required": "Authentication Required",
"auth_required_description": "You must sign in to access the admin interface.",
"welcome": "Welcome to the admin panel.",
- "members_title": "Members",
"members_description": "Manage network members and operators.",
- "node_tags_title": "Node Tags",
"node_tags_description": "Manage custom tags and metadata for network nodes."
},
"admin_members": {
- "title": "Members",
"network_members": "Network Members ({{count}})",
- "add_member": "Add Member",
- "add_new_member": "Add New Member",
- "edit_member": "Edit Member",
- "delete_member": "Delete Member",
"member_id": "Member ID",
"member_id_hint": "Unique identifier (letters, numbers, underscore)",
"no_members_yet": "No members configured yet.",
"no_members_hint": "Click \"Add Member\" to create the first member.",
"delete_confirm": "Are you sure you want to delete member
{{name}}?",
"cannot_be_undone": "This action cannot be undone.",
- "member_added": "Member added successfully",
- "member_updated": "Member updated successfully",
- "member_deleted": "Member deleted successfully"
+ "entity_added": "Member added successfully",
+ "entity_updated": "Member updated successfully",
+ "entity_deleted": "Member deleted successfully"
},
"admin_node_tags": {
- "title": "Node Tags",
"select_node": "Select Node",
"select_node_placeholder": "-- Select a node --",
"load_tags": "Load Tags",
- "tags_count": "Tags ({{count}})",
- "add_new_tag": "Add New Tag",
- "add_tag": "Add Tag",
- "edit_tag": "Edit Tag",
- "move_tag": "Move Tag",
- "move_tag_title": "Move Tag to Another Node",
- "move_tag_warning": "This will move the tag from the current node to the destination node.",
- "delete_tag": "Delete Tag",
+ "move_to_another_node": "Move Tag to Another Node",
+ "move_warning": "This will move the tag from the current node to the destination node.",
"delete_tag_confirm": "Are you sure you want to delete the tag \"{{key}}\"?",
"cannot_be_undone": "This action cannot be undone.",
"copy_all": "Copy All",
"copy_all_title": "Copy All Tags to Another Node",
"copy_all_description": "Copy all {{count}} tag(s) from
{{name}} to another node.",
"copy_all_info": "Tags that already exist on the destination node will be skipped. Original tags remain on this node.",
- "copy_tags": "Copy Tags",
"delete_all": "Delete All",
- "delete_all_title": "Delete All Tags",
"delete_all_confirm": "Are you sure you want to delete all {{count}} tag(s) from
{{name}}?",
"delete_all_warning": "This action cannot be undone. All tags will be permanently deleted.",
- "delete_all_tags": "Delete All Tags",
- "view_node": "View Node",
"destination_node": "Destination Node",
"tag_key": "Tag Key",
"no_tags_found": "No tags found for this node.",
"no_tags_hint": "Add a new tag below.",
"select_a_node": "Select a Node",
"select_a_node_description": "Choose a node from the dropdown above to view and manage its tags.",
- "tag_added": "Tag added successfully",
- "tag_updated": "Tag updated successfully",
- "tag_moved": "Tag moved successfully",
- "tag_deleted": "Tag deleted successfully",
- "all_tags_deleted": "All tags deleted successfully",
- "copied_tags": "Copied {{copied}} tag(s), skipped {{skipped}}"
+ "entity_added": "Tag added successfully",
+ "entity_updated": "Tag updated successfully",
+ "entity_moved": "Tag moved successfully",
+ "entity_deleted": "Tag deleted successfully",
+ "all_entities_deleted": "All tags deleted successfully",
+ "copied_entities": "Copied {{copied}} tag(s), skipped {{skipped}}"
},
"footer": {
- "powered_by": "Powered by",
- "discord": "Discord",
- "github": "GitHub",
- "youtube": "YouTube"
+ "powered_by": "Powered by"
}
}
diff --git a/src/meshcore_hub/web/templates/spa.html b/src/meshcore_hub/web/templates/spa.html
index 37ad867..6514c6f 100644
--- a/src/meshcore_hub/web/templates/spa.html
+++ b/src/meshcore_hub/web/templates/spa.html
@@ -150,15 +150,15 @@
{% endif %}
{% if network_contact_email and network_contact_discord %} | {% endif %}
{% if network_contact_discord %}
-
{{ t('footer.discord') }}
+
{{ t('links.discord') }}
{% endif %}
{% if (network_contact_email or network_contact_discord) and network_contact_github %} | {% endif %}
{% if network_contact_github %}
-
{{ t('footer.github') }}
+
{{ t('links.github') }}
{% endif %}
{% if (network_contact_email or network_contact_discord or network_contact_github) and network_contact_youtube %} | {% endif %}
{% if network_contact_youtube %}
-
{{ t('footer.youtube') }}
+
{{ t('links.youtube') }}
{% endif %}
{% if admin_enabled %}{{ t('nav.admin') }} | {% endif %}{{ t('footer.powered_by') }} MeshCore Hub {{ version }}