Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
1fe3dd0
feat(i18n): add application management translations
stephdl Nov 13, 2025
ba43e89
feat(ui): update software center icon and add applications link
stephdl Nov 13, 2025
1981b22
feat(ui): add RestartModuleModal component for application restart co…
stephdl Nov 13, 2025
fc0426f
feat(ui): add SetInstanceLabelModal component for editing instance la…
stephdl Nov 13, 2025
9ee0b5e
feat(ui): add route for Applications Center view
stephdl Nov 13, 2025
3dbaa0e
feat(ui): update navigation from software center to applications center
stephdl Nov 13, 2025
4997002
feat(ui): refactor RestartModuleModal and SetInstanceLabelModal integ…
stephdl Nov 13, 2025
c20e0f2
feat(ui): add Applications Center view with module management features
stephdl Nov 13, 2025
cb4101b
feat(ui): remove isStableUpdateAvailable method from ApplicationsCenter
stephdl Nov 13, 2025
41b4b46
feat(ui): remove installedModules computed property from Applications…
stephdl Nov 13, 2025
3872068
feat(ui): remove console log from updateInstance method in SoftwareCe…
stephdl Nov 13, 2025
89cc40a
fix(ui): handle potential null value for node_ui_name in search filter
stephdl Nov 13, 2025
b10a4a0
fix(ui): update uninstalling and restarting messages for clarity
stephdl Nov 13, 2025
20d2ab5
refactor(ui): remove updateModules method and related task handling
stephdl Nov 13, 2025
0b3a913
refactor(ui): remove unused appToUpdate property from ApplicationsCen…
stephdl Nov 13, 2025
300b171
fix(ui): capitalize module names in ApplicationsCenter component
stephdl Nov 13, 2025
32d0f5f
refactor(ui): remove commented-out listRepositories call in Applicati…
stephdl Nov 13, 2025
6bf459c
fix(ui): update comment to improve clarity in ApplicationsCenter comp…
stephdl Nov 13, 2025
08a34b4
fix(ui): update i18nTableColumns method to clarify last column for ov…
stephdl Nov 13, 2025
a07efcc
feat(agent): add set-note action and input validation schema
stephdl Nov 13, 2025
c704dec
feat(modules): add ui_note field to list_installed function for enhan…
stephdl Nov 13, 2025
3e0d50f
feat(applications): add note functionality with modal for application…
stephdl Nov 14, 2025
e25eddf
feat(applications): enhance note functionality with edit option and v…
stephdl Nov 14, 2025
23f13bf
refactor(software_center): update translation keys for instance manag…
stephdl Nov 14, 2025
c7c8449
feat(applications): add cloneOrMoveAppData to enhance clone/move func…
stephdl Nov 14, 2025
5b45780
feat(applications): update updateInstance method to handle testing ve…
stephdl Nov 14, 2025
bc5b2e4
Apply suggestions from translation review
stephdl Nov 18, 2025
22a9a5c
Apply suggestions from translation review
stephdl Nov 19, 2025
90c74e5
Apply suggestions from code review
stephdl Nov 19, 2025
72b9852
Apply suggestions from code review
stephdl Nov 19, 2025
8817d2d
Update core/ui/src/components/applications-center/AddNoteModal.vue
stephdl Nov 19, 2025
45e9d07
Add loading state to modals and improve template formatting
stephdl Nov 19, 2025
5731b73
Update core/ui/src/views/ApplicationsCenter.vue
stephdl Nov 19, 2025
e408e79
Update core/ui/src/views/ApplicationsCenter.vue
stephdl Nov 19, 2025
cd4434d
Update @nethserver/ns8-ui-lib to version 1.6.0 in package.json and ya…
stephdl Nov 19, 2025
a4cd209
Merge branch 'sdl-7663' of github.com:NethServer/ns8-core into sdl-7663
stephdl Nov 19, 2025
ea00b9f
Remove unnecessary styles from module logo in ApplicationsCenter.vue
stephdl Nov 19, 2025
5e5ba34
Merge branch 'main' into sdl-7663
stephdl Nov 19, 2025
4e3d70d
Refactor NodeCard and NodeDetail components to use cv-link for applic…
stephdl Nov 19, 2025
e6e9c37
Add cloneOrMoveAppData to cloneOrMove instance in ApplicationsCenter
stephdl Nov 19, 2025
a500e80
Add filter applications placeholder text in ApplicationsCenter
stephdl Nov 20, 2025
93cfd1a
Add tooltips for software center and applications titles to enhance u…
stephdl Nov 20, 2025
c096b47
Add AppInfoModal and implement app info display on logo click in Appl…
stephdl Nov 20, 2025
76d422d
Enhance tooltips in ApplicationsCenter and SoftwareCenter with naviga…
stephdl Nov 20, 2025
7803a47
Remove unused appToUninstall variable from ApplicationsCenter to stre…
stephdl Nov 21, 2025
08a72d0
Update application description wording for consistency in translation…
stephdl Nov 21, 2025
f1899b6
Refactor AddNoteModal layout for improved styling and structure
stephdl Nov 21, 2025
6f6831a
Improve layout of AddNoteModal by adjusting alignment and text positi…
stephdl Nov 21, 2025
b0bb7fa
Refactor goToApplications method to use object syntax for router push
stephdl Nov 21, 2025
2485e1b
Update core/ui/src/components/software-center/SetInstanceLabelModal.vue
stephdl Nov 21, 2025
faa9439
Refactor SetInstanceLabelModal and related components to remove unuse…
stephdl Nov 21, 2025
e7c4168
Add pictogram to empty state in ApplicationsCenter view
stephdl Nov 21, 2025
b909271
Refactor ApplicationsCenter to replace cloneOrMoveAppData with appInf…
stephdl Nov 21, 2025
762a372
Refactor ApplicationsCenter to simplify overflow menu items by removi…
stephdl Nov 21, 2025
5c84817
Refactor ApplicationsCenter to use template slot for icon in NsMenuIt…
stephdl Nov 21, 2025
71dbd62
Fix component name from SoftwareCenter to ApplicationsCenter for cons…
stephdl Nov 21, 2025
b270320
Refactor comment in ApplicationsCenter to clarify purpose of workarou…
stephdl Nov 21, 2025
6d32084
Add restartModule property to component data for state management
stephdl Nov 21, 2025
e83657a
Remove default filter setting logic from created lifecycle hook in Ap…
stephdl Nov 21, 2025
6e01bcc
Refactor SetInstanceLabelModal to improve error handling and streamli…
stephdl Nov 21, 2025
d69df08
Refactor RestartModuleModal and ApplicationsCenter to enhance error h…
stephdl Nov 21, 2025
79d8ac6
Remove unused form elements from RestartModuleModal and SetInstanceLa…
stephdl Nov 21, 2025
25aa9eb
Refactor AddNoteModal and ApplicationsCenter to improve state managem…
stephdl Nov 21, 2025
df362a9
Refactor tooltips in ApplicationsCenter and SoftwareCenter to use i18…
stephdl Nov 24, 2025
e8b6737
Refactor SetInstanceLabelModal to unify inputLabel handling and impro…
stephdl Nov 24, 2025
35d8ed8
Add validation messages for instance label length and character restr…
stephdl Nov 24, 2025
acff079
Fix validation logic for note length and update primary button state …
stephdl Nov 24, 2025
e2503fc
Reset note input on modal close in AddNoteModal
stephdl Nov 24, 2025
cdedea5
Make application names clickable in ApplicationsCenter and adjust fon…
stephdl Nov 24, 2025
fc6fb83
Remove note reset on modal close in AddNoteModal and inputLabel reset…
stephdl Nov 24, 2025
fe02757
Fix validation logic for note input in AddNoteModal to handle alphanu…
stephdl Nov 24, 2025
08774f5
Enhance RestartModuleModal with warning notification and improve erro…
stephdl Nov 24, 2025
419721f
fix: improve query parameters management
andre8244 Nov 25, 2025
1d82dfc
fix: link to applications page
andre8244 Nov 25, 2025
5a94234
fix: focus input field when opening modals
andre8244 Nov 25, 2025
e77b1b4
Apply suggestions from translation review
stephdl Nov 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions core/imageroot/usr/local/agent/actions/set-note/50set_note
Original file line number Diff line number Diff line change
@@ -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'])
Original file line number Diff line number Diff line change
@@ -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
}
}
}
1 change: 1 addition & 0 deletions core/imageroot/usr/local/agent/pypkg/cluster/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, ""),
Expand Down
2 changes: 1 addition & 1 deletion core/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
51 changes: 47 additions & 4 deletions core/ui/public/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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"
}
}
164 changes: 164 additions & 0 deletions core/ui/src/components/applications-center/AddNoteModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<template>
<NsModal
:visible="visible"
:isLoading="loading.saveNote"
@primary-click="saveNote"
:primary-button-disabled="invalidNoteAlphanum ? true : false"
@modal-hidden="onModalHidden"
size="default"
>
<template slot="title">{{
isEdit ? $t("applications.edit_note") : $t("applications.add_note")
}}</template>
<template slot="content">
<div class="mg-bottom-md">{{ $t("applications.note_description") }}</div>
<div class="flex flex-col">
<div class="flex items-center justify-between">
<div class="bx--label no-mg-bottom">
{{ $t("applications.note") }}
</div>
<div class="bx--label no-mg-bottom text-right">
{{ note.length }}/100
</div>
</div>
<cv-text-area
v-model="note"
:placeholder="$t('applications.enter_note')"
:maxLength="100"
:rows="4"
:disabled="loading.saveNote"
:invalid-message="invalidNoteAlphanum || invalidNoteLength"
:helper-text="$t('applications.note_helper_text')"
data-modal-primary-focus
/>
<cv-inline-notification
v-if="error.saveNote"
kind="error"
:title="$t('action.set-note')"
:description="error"
:showCloseButton="false"
/>
</div>
</template>
<template slot="secondary-button">{{ $t("common.cancel") }}</template>
<template slot="primary-button">{{
isEdit ? $t("common.save") : $t("applications.add_note")
}}</template>
</NsModal>
</template>

<script>
import { UtilService, TaskService, IconService } from "@nethserver/ns8-ui-lib";
import to from "await-to-js";
export default {
name: "saveNoteModal",
mixins: [UtilService, TaskService, IconService],
props: {
visible: {
type: Boolean,
required: true,
},
isEdit: {
type: Boolean,
default: false,
},
currentNote: {
type: String,
default: "",
},
noteInstance: Object,
},
data() {
return {
note: this.currentNote,
error: { saveNote: "" },
loading: { saveNote: false },
};
},
watch: {
currentNote(newVal) {
this.note = newVal;
},
visible(newVal) {
if (newVal) {
this.note = this.currentNote;
}
},
},
computed: {
invalidNoteAlphanum() {
const alphanumRegex = /^[a-zA-Z0-9 ]*$/;
if (!alphanumRegex.test(this.note)) {
return this.$t("applications.note_alphanum_only");
}
return "";
},
invalidNoteLength() {
if (this.note.length == 100) {
return this.$t("applications.note_too_long");
}
return "";
},
},
methods: {
onModalHidden() {
this.clearErrors();
this.$emit("hide");
},
async saveNote() {
this.error.saveNote = "";
this.loading.saveNote = true;
const taskAction = "set-note";
const eventId = this.getUuid();

// register to task completion
this.$root.$once(
`${taskAction}-completed-${eventId}`,
this.saveNoteCompleted
);
// register to task error
this.$root.$once(
`${taskAction}-aborted-${eventId}`,
this.saveNoteAborted
);

const res = await to(
this.createModuleTaskForApp(this.noteInstance.id, {
action: taskAction,
data: {
note: this.note,
},
extra: {
title: this.$t("action." + taskAction),
isNotificationHidden: true,
eventId,
},
})
);
const err = res[0];

if (err) {
console.error(`error creating task ${taskAction}`, err);
this.error.saveNote = this.getErrorMessage(err);
this.loading.saveNote = false;
return;
}
// emit event to close modal
this.$emit("hide");
},
saveNoteAborted(taskResult, taskContext) {
console.error(`${taskContext.action} aborted`, taskResult);
this.error.saveNote = this.$t("error.generic_error");
this.loading.saveNote = false;
},
saveNoteCompleted() {
this.loading.saveNote = false;
this.$emit("hide");
this.$emit("saveNoteCompleted");
},
},
};
</script>
<style scoped lang="scss">
@import "../../styles/carbon-utils";
</style>
11 changes: 5 additions & 6 deletions core/ui/src/components/nodes/NodeCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,9 @@
<div class="tr">
<div class="td label">{{ $t("nodes.applications") }}</div>
<div class="td">
<!-- <cv-link v-if="applications" @click.prevent="goToApplications"> -->
{{ applications }}
<!-- </cv-link> -->
<!-- <span v-else>-</span> -->
<cv-link v-if="applications" @click.prevent="goToApplications">
{{ applications }}
</cv-link>
</div>
</div>
</div>
Expand Down Expand Up @@ -245,8 +244,8 @@ export default {
methods: {
goToApplications() {
this.$router.push({
name: "applications",
params: { nodeId: this.nodeId },
path: "/applications-center",
query: { selectedNodeId: this.nodeId },
});
},
},
Expand Down
12 changes: 11 additions & 1 deletion core/ui/src/components/shell/SideMenuContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,17 @@
@click="goTo('/software-center')"
:active="isLinkActive('/software-center')"
>
<template v-slot:nav-icon><Application20 /></template>
<template v-slot:nav-icon><ShoppingCatalog20 /></template>
<span>{{ $t("software_center.title") }}</span>
</cv-side-nav-link>
<!-- Applications -->
<cv-side-nav-link
@click="goTo('/applications-center')"
:active="isLinkActive('/applications-center')"
>
<template v-slot:nav-icon><Application20 /></template>
<span>{{ $t("applications.title") }}</span>
</cv-side-nav-link>
<!-- backup -->
<cv-side-nav-link
@click="goTo('/backup')"
Expand Down Expand Up @@ -93,6 +101,7 @@ import Activity20 from "@carbon/icons-vue/es/activity/20";
import Chip20 from "@carbon/icons-vue/es/chip/20";
import Information20 from "@carbon/icons-vue/es/information/20";
import Police20 from "@carbon/icons-vue/es/police/20";
import ShoppingCatalog20 from "@carbon/icons-vue/es/shopping--catalog/20";
import { mapActions } from "vuex";
import CvSideNavDivider from "@carbon/vue/src/components/cv-ui-shell/cv-side-nav-divider.vue";

Expand All @@ -109,6 +118,7 @@ export default {
Information20,
CvSideNavDivider,
Police20,
ShoppingCatalog20,
},
data() {
return {};
Expand Down
Loading