diff --git a/core/imageroot/usr/local/agent/actions/set-note/50set_note b/core/imageroot/usr/local/agent/actions/set-note/50set_note
new file mode 100755
index 000000000..6c274ee4c
--- /dev/null
+++ b/core/imageroot/usr/local/agent/actions/set-note/50set_note
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (C) 2025 Nethesis S.r.l.
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+import json
+import sys
+import agent
+import os
+
+agent_id = os.environ['AGENT_ID']
+
+request = json.load(sys.stdin)
+
+rdb = agent.redis_connect(privileged=True)
+rdb.set(agent_id + '/ui_note', request['note'])
diff --git a/core/imageroot/usr/local/agent/actions/set-note/validate-input.json b/core/imageroot/usr/local/agent/actions/set-note/validate-input.json
new file mode 100644
index 000000000..225ccb2cc
--- /dev/null
+++ b/core/imageroot/usr/local/agent/actions/set-note/validate-input.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "set-note input",
+ "$id": "http://schema.nethserver.org/agent/set-note-input.json",
+ "description": "A short note to help identify or describe a module instance. The note is visible in Applications Center.",
+ "examples": [
+ {
+ "note": "this module is for my personal use"
+ }
+ ],
+ "type": "object",
+ "required": [
+ "note"
+ ],
+ "properties": {
+ "note": {
+ "type": "string",
+ "maxLength": 100
+ }
+ }
+}
diff --git a/core/imageroot/usr/local/agent/pypkg/cluster/modules.py b/core/imageroot/usr/local/agent/pypkg/cluster/modules.py
index 96d2fa889..123a292ff 100644
--- a/core/imageroot/usr/local/agent/pypkg/cluster/modules.py
+++ b/core/imageroot/usr/local/agent/pypkg/cluster/modules.py
@@ -387,6 +387,7 @@ def list_installed(rdb, skip_core_modules = False):
'version': mtag,
'module': msource.rsplit("/", 1)[1],
'ui_name': rdb.get(f'module/{module_id}/ui_name') or "",
+ 'ui_note': rdb.get(f'module/{module_id}/ui_note') or "",
'node': mnode_id,
'node_ui_name': hnode_names[mnode_id],
'logo': logos.get(module_id, ""),
diff --git a/core/ui/package.json b/core/ui/package.json
index 01e5b9b80..65fd6b089 100644
--- a/core/ui/package.json
+++ b/core/ui/package.json
@@ -16,7 +16,7 @@
"@carbon/icons-vue": "^10.37.0",
"@carbon/themes": "^10.34.0",
"@carbon/vue": "^2.40.0",
- "@nethserver/ns8-ui-lib": "^1.5.0",
+ "@nethserver/ns8-ui-lib": "^1.6.0",
"await-to-js": "^3.0.0",
"axios": "^0.30.2",
"carbon-components": "^10.41.0",
diff --git a/core/ui/public/i18n/en/translation.json b/core/ui/public/i18n/en/translation.json
index 509c8ff73..86c01638e 100644
--- a/core/ui/public/i18n/en/translation.json
+++ b/core/ui/public/i18n/en/translation.json
@@ -92,7 +92,9 @@
"not_available": "Not available",
"release_notes": "Release notes",
"plus_others": "+{num} other | +{num} others",
- "choose_a_node": "Choose a node"
+ "choose_a_node": "Choose a node",
+ "type": "Type",
+ "any": "Any"
},
"error": {
"error": "Error",
@@ -425,7 +427,8 @@
"get-metrics-id": "Get metrics ID",
"restart-module": "Restart instance",
"list-alerts": "List alerts",
- "list-nodes": "List nodes"
+ "list-nodes": "List nodes",
+ "set-note": "Set note"
},
"network": {
"title": "Network"
@@ -951,6 +954,8 @@
},
"software_center": {
"title": "Software center",
+ "title_tooltip": "Discover, install and update applications in your cluster. To manage installed applications, go to {applications} page",
+ "go_to_applications_center": "Go to applications center",
"search_placeholder": "Search apps",
"software_updates": "Updates",
"you_have_updates": "You have {numUpdates} app to update | You have {numUpdates} apps to update",
@@ -1004,7 +1009,7 @@
"no_instance_installed": "No instance installed",
"instance": "Instance",
"instance_label": "App instance label",
- "instance_label_tooltip": "You can assign the app instance an easy to remember name",
+ "instance_label_tooltip": "You can give the application a memorable label to help recall its name.",
"edit_instance_label": "Edit instance label",
"app_managed_in": "This app is managed in",
"reload_software_repositories": "Reload repositories",
@@ -1099,7 +1104,9 @@
"rootfull_certification_level_too_low": "Apps with administrative privileges must have a minimum certification level of {certification_min}/5 to be installed"
},
"migrating_app_title": "This app instance is undergoing migration",
- "migrating_app_description": "You'll be able to use {name} again once the migration from NethServer 7 is complete."
+ "migrating_app_description": "You'll be able to use {name} again once the migration from NethServer 7 is complete.",
+ "instance_label_too_long": "Application label must be 24 characters or less",
+ "instance_label_alphanum_only": "Application label can only contain alphanumeric characters and spaces"
},
"system_logs": {
"title": "System logs",
@@ -1199,6 +1206,7 @@
"title": "Cluster status",
"go_to_nodes": "Go to Nodes",
"go_to_software_center": "Go to Software center",
+ "go_to_applications": "Go to Applications",
"go_to_backup": "Go to Backup",
"backups_failed_c": "{num} app backup failed | {num} app backups failed",
"backup_disabled_c": "{num} backup disabled | {num} backups disabled",
@@ -1676,5 +1684,40 @@
"available_with_subscription_title": "Activate subscription to enable this feature",
"available_with_subscription": "Send a stream of security logs from applications and nodes of this cluster to Cloud Log Manager, where you can store, archive, and search them in a central place.",
"cluster_id_notification": "Security logs from this cluster are available in the Cloud Log Manager UI under the host '{clusterId}'."
+ },
+ "applications": {
+ "title": "Applications",
+ "title_tooltip": "This page displays all the applications installed on the cluster and lets you manage them easily. To install a new application, go to {software} page.",
+ "go_to_software_center": "Go to Software center",
+ "no_application": "No application installed",
+ "no_application_description": "You can find and install applications in the Software center.",
+ "name": "Name",
+ "version": "Version",
+ "type": "Type",
+ "node": "Node",
+ "status": "Status",
+ "update_available": "Update available",
+ "edit_label": "Edit label",
+ "restart": "Restart",
+ "open": "Open",
+ "clone": "Clone",
+ "move": "Move",
+ "uninstall": "Uninstall",
+ "instance_uninstallation": "Uninstall {instance}",
+ "uninstalling": "Uninstalling",
+ "restart_instance_name": "Restart {instance}",
+ "update": "Update",
+ "app_uninstallation": "Uninstall {app}",
+ "uninstall_app": "Uninstall {name}? App data will be deleted too. This action is NOT reversible",
+ "restarting": "Restarting",
+ "add_note": "Add note",
+ "edit_note": "Edit note",
+ "note": "Note",
+ "enter_note": "Enter note (max 100 characters)",
+ "note_too_long": "Note must be 100 characters or less",
+ "note_description": "A short note to help identify or describe this application.",
+ "note_alphanum_only": "Note can only contain alphanumeric characters and spaces",
+ "note_helper_text": "Only alphanumeric characters and spaces are allowed",
+ "filter_applications": "Filter applications"
}
}
diff --git a/core/ui/src/components/applications-center/AddNoteModal.vue b/core/ui/src/components/applications-center/AddNoteModal.vue
new file mode 100644
index 000000000..7ff76d204
--- /dev/null
+++ b/core/ui/src/components/applications-center/AddNoteModal.vue
@@ -0,0 +1,164 @@
+
+
+ {{ $t("common.no_search_results_description") }} +
+