diff --git a/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.css b/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.css index 0ec67f1..f2e2a3b 100644 --- a/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.css +++ b/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.css @@ -63,4 +63,28 @@ justify-content: flex-end; gap: 1em; padding: 0em 1.5em 1.5em 1.5em; +} + +.software-tab-hint { + color: #666; + font-size: 0.85em; + margin: 0 0 12px 0; +} + +.software-list-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 8px; + font-size: 0.85em; + color: #555; +} + +.clear-selection-link { + background: none; + border: none; + color: #3f51b5; + cursor: pointer; + text-decoration: underline; + padding: 0; } \ No newline at end of file diff --git a/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.html b/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.html index d19dfed..7f56836 100644 --- a/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.html +++ b/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.html @@ -12,14 +12,6 @@ {{ 'labelComments' | translate }} - - {{ 'selectOrganizationalUnit' | translate }} - - - {{ ou.name }} - - - {{ 'selectOperativeSystem' | translate }} @@ -33,11 +25,13 @@ + {{ 'selectSoftwareHint' | translate }} + - @@ -46,9 +40,17 @@ + + {{ 'selectedSoftwareCount' | translate: { count: selectedSoftwares.length } }} + + {{ 'clearAll' | translate }} + + + - + {{ software.name }} delete diff --git a/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.ts b/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.ts index 36d3260..0665fb4 100644 --- a/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.ts +++ b/ogWebconsole/src/app/components/software-profile/create-software-profile/create-software-profile.component.ts @@ -1,7 +1,7 @@ import { inject } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { Component, Inject, OnInit } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; import { HttpClient } from '@angular/common/http'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ToastrService } from 'ngx-toastr'; @@ -21,11 +21,8 @@ export class CreateSoftwareProfileComponent implements OnInit { baseUrl: string; private apiUrl: string; formGroup: FormGroup; - softwareCollection: any[] = []; - organizationalUnits: any[] = []; operativeSystems: any[] = []; softwareProfileId: string | null = null; - selectedSoftware: any; selectedSoftwares: any[] = []; softwareControl = new FormControl(); filteredSoftware!: Observable; @@ -45,7 +42,6 @@ export class CreateSoftwareProfileComponent implements OnInit { this.formGroup = this.fb.group({ description: [''], comments: [''], - organizationalUnit: [null, Validators.required], operativeSystem: [null] }); } @@ -54,10 +50,9 @@ export class CreateSoftwareProfileComponent implements OnInit { if (this.data) { this.softwareProfileId = this.data['@id']; this.patchFormData(); + this.loadSoftware(); } - this.loadSoftware(); - this.loadOrganizationalUnits(); this.loadOperativeSystems(); this.filteredSoftware = this.softwareControl.valueChanges.pipe( @@ -71,15 +66,14 @@ export class CreateSoftwareProfileComponent implements OnInit { this.formGroup.patchValue({ description: this.data.description || '', comments: this.data.comments || '', - organizationalUnit: this.data.organizationalUnit ? this.data.organizationalUnit['@id'] : null, operativeSystem: this.data.operativeSystem ? this.data.operativeSystem['@id'] : null, }); } loadSoftware() { - this.http.get(`${this.baseUrl}/software?softwareProfileId=${this.data.id}&page=1&itemsPerPage=10`).subscribe( + this.http.get(`${this.baseUrl}/software?softwareProfileId=${this.data.id}&page=1&itemsPerPage=1000`).subscribe( response => { - this.softwareCollection = response['hydra:member']; + this.selectedSoftwares = response['hydra:member']; }, error => { console.error(this.translate.instant('softwareFetchingError'), error); @@ -87,17 +81,6 @@ export class CreateSoftwareProfileComponent implements OnInit { ); } - loadOrganizationalUnits() { - this.http.get(`${this.baseUrl}/organizational-units?page=1&itemsPerPage=10000`).subscribe( - response => { - this.organizationalUnits = response['hydra:member']; - }, - error => { - console.error(this.translate.instant('errorFetchingOrganizationalUnits1'), error); - } - ); - } - loadOperativeSystems() { this.http.get(`${this.baseUrl}/operative-systems?page=1&itemsPerPage=10000`).subscribe( response => { @@ -110,33 +93,36 @@ export class CreateSoftwareProfileComponent implements OnInit { } private _filterSoftware(value: string): Observable { - return this.softwareDataService.getSoftwareCollection({ name: value }).pipe( - map(response => response || []) + const filters = { name: value || '', itemsPerPage: '15' }; + + return this.softwareDataService.getSoftwareCollection(filters).pipe( + map(response => (response || []).filter(software => !this.isSelected(software))) ); } + isSelected(software: any): boolean { + return this.selectedSoftwares.some(s => s.id === software.id); + } + displayFnClient(client: any): string { return client && client.name ? client.name : ''; } onOptionClientSelected(software: any) { - if (!this.selectedSoftwares.find(s => s.id === software.id)) { + if (!this.isSelected(software)) { this.selectedSoftwares.push(software); } this.softwareControl.setValue(''); } - addSoftware() { - const software = this.softwareCollection.find(s => s.id === this.selectedSoftware); - if (software && !this.selectedSoftwares.includes(software)) { - this.selectedSoftwares.push(software); - } - } - removeSoftware(software: any) { this.selectedSoftwares = this.selectedSoftwares.filter(s => s.id !== software.id); } + clearSelectedSoftwares(): void { + this.selectedSoftwares = []; + } + onCancel(event: Event): void { event.preventDefault(); this.dialogRef.close(); @@ -148,7 +134,6 @@ export class CreateSoftwareProfileComponent implements OnInit { description: this.formGroup.value.description, comments: this.formGroup.value.comments, softwareCollection: this.selectedSoftwares.map(s => s['@id']), - organizationalUnit: this.formGroup.value.organizationalUnit, operativeSystem: this.formGroup.value.operativeSystem }; diff --git a/ogWebconsole/src/locale/cat.json b/ogWebconsole/src/locale/cat.json index 4836deb..98da817 100644 --- a/ogWebconsole/src/locale/cat.json +++ b/ogWebconsole/src/locale/cat.json @@ -65,6 +65,7 @@ "advancedParameters": "Paràmetres avançats", "all": "Tots", "allowedOrganizationalUnits": "Unitats Organitzacionals Permeses", + "andMoreClients": "i {{count}} més", "anErrorOccurredWhileLoading": "S'ha produït un error en carregar les unitats organitzatives", "apiPort": "Port API", "application": "Aplicació", @@ -211,6 +212,7 @@ "classroomStatusUpdated": "Estat de l'aula actualitzat", "classroomTitle": "Aula", "classroomWillBe": "L'aula estarà", + "clearAll": "Treure tots", "clearClientSearch": "Netejar cerca de client", "clearInputSearch": "Netejar cerca", "clearTreeSearch": "Netejar cerca a l'arbre", @@ -235,6 +237,7 @@ "clientOff": "Client apagat", "clientOgLive": "Client OGLive", "clientPropertiesTitle": "Propietats del client", + "clients": "Clients", "clientSelectStepText": "Selecciona un client per veure les traces associades.", "clientsPerPage": "Clients per pàgina", "clientsPerPageHint": "Nombre de clients mostrats per pàgina al llistat", @@ -1017,6 +1020,7 @@ "noFilesInDirectory": "No hi ha fitxers en aquest directori", "noGitInfoForPartition": "No s'ha trobat informació de Git per a aquesta partició", "noHardwareAssociatedToProfile": "No hi ha maquinari associat a aquest perfil", + "noHardwareProfileAssigned": "Aquest client no té cap perfil de maquinari assignat", "noInternalElementsMessage": "No hi ha elements interns", "noLogsAvailable": "noLogsAvailable", "noOgLivesInServer": "No hi ha OgLives en aquest servidor", @@ -1029,6 +1033,7 @@ "noReposAvailableCreateNew": "No hi ha repositoris disponibles. Crea un de nou per continuar.", "noResultsMessage": "No hi ha resultats per mostrar.", "noSavedScripts": "No hi ha scripts desats disponibles", + "noSoftwareProfileAssigned": "Sense perfil de programari assignat", "notAccessible": "No accessible", "noTags": "Sense etiquetes", "notAvailableLowercase": "no disponible", @@ -1266,6 +1271,7 @@ "selectedClients": "Clients seleccionats", "selectedClientsTitle": "Clients seleccionats:", "selectedCommandsTitle": "Comandaments Seleccionats", + "selectedSoftwareCount": "{{count}} programari afegit", "selectGitRepoHint": "Selecciona el repositori git per obtenir les imatges disponibles.", "selectGitRepoOs": "Seleccionar repositori git / SO", "selectGitRepository": "Seleccionar repositori Git", @@ -1286,6 +1292,7 @@ "selectRepoToView": "Tria un repositori de la llista per veure el seu estat detallat.", "selectScriptToRun": "Seleccioni script a executar", "selectScriptToView": "Tria un script desat de la llista per veure el seu contingut i configurar paràmetres.", + "selectSoftwareHint": "Escriu per cercar i prem Retorn o fes clic per afegir-lo. El camp s'esborra automàticament perquè puguis continuar afegint programari sense interrupcions.", "selectSoftwareToAdd": "Seleccioni programari per afegir", "selectTask": "Seleccioni una tasca", "selectTemplateDescription": "Seleccioni plantilla", diff --git a/ogWebconsole/src/locale/en.json b/ogWebconsole/src/locale/en.json index a605c7e..a4bc94e 100644 --- a/ogWebconsole/src/locale/en.json +++ b/ogWebconsole/src/locale/en.json @@ -65,6 +65,7 @@ "advancedParameters": "Advanced parameters", "all": "All", "allowedOrganizationalUnits": "Allowed Organizational Units", + "andMoreClients": "and {{count}} more", "anErrorOccurredWhileLoading": "An error occurred while loading the organizational units", "apiPort": "API Port", "application": "Application", @@ -211,6 +212,7 @@ "classroomStatusUpdated": "Classroom status updated", "classroomTitle": "Classroom", "classroomWillBe": "The classroom will be", + "clearAll": "Clear all", "clearClientSearch": "Clear client search", "clearInputSearch": "Clear input search", "clearTreeSearch": "Clear tree search", @@ -235,6 +237,7 @@ "clientOff": "Client off", "clientOgLive": "OGLive client", "clientPropertiesTitle": "Client properties", + "clients": "Clients", "clientSelectStepText": "Select a client to see the associated traces.", "clientsPerPage": "Clients per page", "clientsPerPageHint": "Number of clients shown per page in the list", @@ -1017,7 +1020,7 @@ "noFilesInDirectory": "There are no files in this directory", "noGitInfoForPartition": "No Git information found for this partition", "noHardwareAssociatedToProfile": "There is no hardware associated with this profile", - "noHardwareProfileAssigned": "This client does not have its own hardware profile assigned", + "noHardwareProfileAssigned": "This client does not have any hardware profile assigned", "noInternalElementsMessage": "No internal elements", "noLogsAvailable": "noLogsAvailable", "noOgLivesInServer": "There are no OgLives on this server", @@ -1030,6 +1033,7 @@ "noReposAvailableCreateNew": "No repositories available. Create a new one to continue.", "noResultsMessage": "No results to display.", "noSavedScripts": "No saved scripts available", + "noSoftwareProfileAssigned": "No software profile assigned", "notAccessible": "Not accessible", "noTags": "No tags", "notAvailableLowercase": "not available", @@ -1267,6 +1271,7 @@ "selectedClients": "Selected clients", "selectedClientsTitle": "Selected clients:", "selectedCommandsTitle": "Selected Commands", + "selectedSoftwareCount": "{{count}} software added", "selectGitRepoHint": "Select the git repository to get available images.", "selectGitRepoOs": "Select git repository / OS", "selectGitRepository": "Select Git repository", @@ -1287,6 +1292,7 @@ "selectRepoToView": "Select a repository from the list to view its detailed status.", "selectScriptToRun": "Select script to run", "selectScriptToView": "Select a saved script from the list to view its content and configure parameters.", + "selectSoftwareHint": "Type to search and press Enter or click to add it. The field clears automatically so you can keep adding software without interruptions.", "selectSoftwareToAdd": "Select software to add", "selectTask": "Select a task", "selectTemplateDescription": "Select template description", diff --git a/ogWebconsole/src/locale/es.json b/ogWebconsole/src/locale/es.json index ae8f7f4..2b59169 100644 --- a/ogWebconsole/src/locale/es.json +++ b/ogWebconsole/src/locale/es.json @@ -65,6 +65,7 @@ "advancedParameters": "Parámetros avanzados", "all": "Todos", "allowedOrganizationalUnits": "Unidades Organizacionales Permitidas", + "andMoreClients": "y {{count}} más", "anErrorOccurredWhileLoading": "Ocurrió un error al cargar las unidades organizativas", "apiPort": "Puerto API", "application": "Aplicacion", @@ -211,6 +212,7 @@ "classroomStatusUpdated": "Estado del aula actualizado", "classroomTitle": "Aula", "classroomWillBe": "El aula estará", + "clearAll": "Quitar todos", "clearClientSearch": "Limpiar búsqueda de cliente", "clearInputSearch": "Limpiar búsqueda", "clearTreeSearch": "Limpiar búsqueda en el árbol", @@ -235,6 +237,7 @@ "clientOff": "Cliente apagado", "clientOgLive": "Cliente OGLive", "clientPropertiesTitle": "Propiedades del cliente", + "clients": "Clientes", "clientSelectStepText": "Selecciona un cliente para ver las trazas asociadas.", "clientsPerPage": "Clientes por página", "clientsPerPageHint": "Número de clientes mostrados por página en el listado", @@ -1017,7 +1020,7 @@ "noFilesInDirectory": "No hay archivos en este directorio", "noGitInfoForPartition": "No se encontró información de Git para esta partición", "noHardwareAssociatedToProfile": "No hay hardware asociado a este perfil", - "noHardwareProfileAssigned": "Este cliente no tiene un perfil de hardware propio asignado", + "noHardwareProfileAssigned": "Este cliente no tiene ningún perfil de hardware asignado", "noInternalElementsMessage": "No hay elementos internos", "noLogsAvailable": "noLogsAvailable", "noOgLivesInServer": "No hay OgLives en este servidor", @@ -1030,6 +1033,7 @@ "noReposAvailableCreateNew": "No hay repositorios disponibles. Crea uno nuevo para continuar.", "noResultsMessage": "No hay resultados para mostrar.", "noSavedScripts": "No hay scripts guardados disponibles", + "noSoftwareProfileAssigned": "Sin perfil de software asignado", "notAccessible": "No accesible", "noTags": "Sin tags", "notAvailableLowercase": "no disponible", @@ -1267,6 +1271,7 @@ "selectedClients": "Clientes seleccionados", "selectedClientsTitle": "Clientes seleccionados:", "selectedCommandsTitle": "Comandos Seleccionados", + "selectedSoftwareCount": "{{count}} programas añadidos", "selectGitRepoHint": "Selecciona el repositorio git para obtener las imágenes disponibles.", "selectGitRepoOs": "Seleccionar repositorio git / SO", "selectGitRepository": "Seleccionar repositorio Git", @@ -1287,6 +1292,7 @@ "selectRepoToView": "Elige un repositorio de la lista para ver su estado detallado.", "selectScriptToRun": "Seleccione script a ejecutar", "selectScriptToView": "Elige un script guardado de la lista para ver su contenido y configurar parámetros.", + "selectSoftwareHint": "Escribe para buscar y pulsa Enter o haz clic para añadir. El campo se vacía automáticamente para que puedas seguir añadiendo software sin interrupciones.", "selectSoftwareToAdd": "Seleccione software para añadir", "selectTask": "Seleccione una tarea", "selectTemplateDescription": "Seleccione plantilla",
{{ 'selectSoftwareHint' | translate }}