summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjm.bardallo <juanmanuel.bardallo@sic.uhu.es>2019-05-02 15:03:30 +0200
committerjm.bardallo <juanmanuel.bardallo@sic.uhu.es>2019-05-02 15:03:30 +0200
commit2272900dfa23f1c5b7c0926e24ab9c435a3d1b5d (patch)
tree1f2b9fc986115cb7ed0852f9c1ccc6179a7aa5a8
parent20fc050be9508646e857ac1e086ebc72181587be (diff)
Posibilidad de añadir clientes mediante fichero dhcp
Añadido perfil software Añadidos comandos: - Ejecutar script - Crear imagen - Deploy de imagen - Iniciar sesion Añadidos los menus
-rw-r--r--admin/WebConsole3/frontend/src/app/api/command.service.ts52
-rw-r--r--admin/WebConsole3/frontend/src/app/api/software-component.service.ts40
-rw-r--r--admin/WebConsole3/frontend/src/app/api/software-profile.service.ts40
-rw-r--r--admin/WebConsole3/frontend/src/app/api/software-type.service.ts40
-rw-r--r--admin/WebConsole3/frontend/src/app/app-routing.module.ts58
-rw-r--r--admin/WebConsole3/frontend/src/app/app.module.ts57
-rw-r--r--admin/WebConsole3/frontend/src/app/form-type/menu.form-type.ts12
-rw-r--r--admin/WebConsole3/frontend/src/app/model/command.ts22
-rw-r--r--admin/WebConsole3/frontend/src/app/model/image.ts44
-rw-r--r--admin/WebConsole3/frontend/src/app/model/menu.ts24
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html139
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.scss5
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts223
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.html98
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.scss3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts188
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.html146
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.scss3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.ts137
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.html95
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.scss3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.ts142
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.html81
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.scss3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.ts80
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/common/og-options/og-commands-options/og-commands-options.component.html14
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.html11
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.ts3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.html24
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.ts11
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component.html (renamed from admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/profiles-group.component.html)94
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component.ts (renamed from admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/profiles-group.component.ts)28
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component.html (renamed from admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/profiles-table.component.html)122
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component.ts (renamed from admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/profiles-table.component.ts)202
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/image/edit/image-edit.component.ts176
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/image/image.component.html6
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.html34
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.scss3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.ts77
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/menu/menu.component.html52
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/menu/menu.component.ts121
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.html4
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.ts17
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.html45
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.ts10
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.html43
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.ts84
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.css0
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.html1
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.ts17
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.html47
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.ts14
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.html61
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.ts100
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.css0
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.html3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.ts19
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.css0
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.html66
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.ts26
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software.component.css0
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software.component.html66
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software.component.scss3
-rw-r--r--admin/WebConsole3/frontend/src/app/pages/software/software.component.ts84
-rw-r--r--admin/WebConsole3/frontend/src/app/serializer/image.serializer.ts21
-rw-r--r--admin/WebConsole3/frontend/src/app/service/og-commands.service.ts471
-rw-r--r--admin/WebConsole3/frontend/src/app/service/og-common.service.ts3
-rw-r--r--admin/WebConsole3/frontend/src/styles.scss4
68 files changed, 3180 insertions, 742 deletions
diff --git a/admin/WebConsole3/frontend/src/app/api/command.service.ts b/admin/WebConsole3/frontend/src/app/api/command.service.ts
index fe77bda3..28b18520 100644
--- a/admin/WebConsole3/frontend/src/app/api/command.service.ts
+++ b/admin/WebConsole3/frontend/src/app/api/command.service.ts
@@ -1,26 +1,26 @@
-import { Injectable } from '@angular/core';
-import { HttpClient} from '@angular/common/http';
-
-import { environment } from '../../environments/environment';
-import { Command } from '../model/command';
-import { CommandSerializer } from '../serializer/command.serializer';
-
-import {ResourceService} from 'globunet-angular/core/providers/api/resource.service';
-import {Observable} from 'rxjs';
-
-
-@Injectable({
- providedIn: 'root'
-})
-export class CommandService extends ResourceService<Command> {
-
- constructor(http: HttpClient) {
- super(http, environment.API_URL, 'commands', new CommandSerializer());
- }
-
- execute(params): Observable<any> {
- const url = this.url + 'executes.json';
- return this.httpClient.post(url, params);
- }
-
-}
+import {Injectable} from '@angular/core';
+import {HttpClient} from '@angular/common/http';
+
+import {environment} from '../../environments/environment';
+import {Command} from '../model/command';
+import {CommandSerializer} from '../serializer/command.serializer';
+
+import {ResourceService} from 'globunet-angular/core/providers/api/resource.service';
+import {Observable} from 'rxjs';
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CommandService extends ResourceService<Command> {
+
+ constructor(http: HttpClient) {
+ super(http, environment.API_URL, 'commands', new CommandSerializer());
+ }
+
+ execute(params): Observable<any> {
+ const url = this.url + '/commands/executes.json';
+ return this.httpClient.post(url, params);
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/api/software-component.service.ts b/admin/WebConsole3/frontend/src/app/api/software-component.service.ts
index 6b794109..b154d41a 100644
--- a/admin/WebConsole3/frontend/src/app/api/software-component.service.ts
+++ b/admin/WebConsole3/frontend/src/app/api/software-component.service.ts
@@ -1,20 +1,20 @@
-import { Injectable } from '@angular/core';
-import { HttpClient} from '@angular/common/http';
-
-import { environment } from '../../environments/environment';
-import { SoftwareComponent } from "../model/software-component";
-import { SoftwareComponentSerializer } from "../serializer/software-component.serializer";
-
-import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
-
-
-@Injectable({
- providedIn: 'root'
-})
-export class SoftwareComponentService extends ResourceService<SoftwareComponent> {
-
- constructor(http: HttpClient){
- super(http, environment.API_URL,"softwareComponents", new SoftwareComponentSerializer());
- }
-
-}
+import { Injectable } from '@angular/core';
+import { HttpClient} from '@angular/common/http';
+
+import { environment } from '../../environments/environment';
+import { SoftwareComponent } from "../model/software-component";
+import { SoftwareComponentSerializer } from "../serializer/software-component.serializer";
+
+import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SoftwareComponentService extends ResourceService<SoftwareComponent> {
+
+ constructor(http: HttpClient){
+ super(http, environment.API_URL,"softwarecomponents", new SoftwareComponentSerializer());
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/api/software-profile.service.ts b/admin/WebConsole3/frontend/src/app/api/software-profile.service.ts
index 442d97a7..92b09e23 100644
--- a/admin/WebConsole3/frontend/src/app/api/software-profile.service.ts
+++ b/admin/WebConsole3/frontend/src/app/api/software-profile.service.ts
@@ -1,20 +1,20 @@
-import { Injectable } from '@angular/core';
-import { HttpClient} from '@angular/common/http';
-
-import { environment } from '../../environments/environment';
-import { SoftwareProfile } from "../model/software-profile";
-import { SoftwareProfileSerializer } from "../serializer/software-profile.serializer";
-
-import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
-
-
-@Injectable({
- providedIn: 'root'
-})
-export class SoftwareProfileService extends ResourceService<SoftwareProfile> {
-
- constructor(http: HttpClient){
- super(http, environment.API_URL,"softwareProfiles", new SoftwareProfileSerializer());
- }
-
-}
+import { Injectable } from '@angular/core';
+import { HttpClient} from '@angular/common/http';
+
+import { environment } from '../../environments/environment';
+import { SoftwareProfile } from "../model/software-profile";
+import { SoftwareProfileSerializer } from "../serializer/software-profile.serializer";
+
+import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SoftwareProfileService extends ResourceService<SoftwareProfile> {
+
+ constructor(http: HttpClient){
+ super(http, environment.API_URL,"softwareprofiles", new SoftwareProfileSerializer());
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/api/software-type.service.ts b/admin/WebConsole3/frontend/src/app/api/software-type.service.ts
index aa2e457e..ccc6eb8f 100644
--- a/admin/WebConsole3/frontend/src/app/api/software-type.service.ts
+++ b/admin/WebConsole3/frontend/src/app/api/software-type.service.ts
@@ -1,20 +1,20 @@
-import { Injectable } from '@angular/core';
-import { HttpClient} from '@angular/common/http';
-
-import { environment } from '../../environments/environment';
-import { SoftwareType } from "../model/software-type";
-import { SoftwareTypeSerializer } from "../serializer/software-type.serializer";
-
-import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
-
-
-@Injectable({
- providedIn: 'root'
-})
-export class SoftwareTypeService extends ResourceService<SoftwareType> {
-
- constructor(http: HttpClient){
- super(http, environment.API_URL,"softwareTypes", new SoftwareTypeSerializer());
- }
-
-}
+import { Injectable } from '@angular/core';
+import { HttpClient} from '@angular/common/http';
+
+import { environment } from '../../environments/environment';
+import { SoftwareType } from "../model/software-type";
+import { SoftwareTypeSerializer } from "../serializer/software-type.serializer";
+
+import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SoftwareTypeService extends ResourceService<SoftwareType> {
+
+ constructor(http: HttpClient){
+ super(http, environment.API_URL,"softwaretypes", new SoftwareTypeSerializer());
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/app-routing.module.ts b/admin/WebConsole3/frontend/src/app/app-routing.module.ts
index 7e5c4c63..80d357fa 100644
--- a/admin/WebConsole3/frontend/src/app/app-routing.module.ts
+++ b/admin/WebConsole3/frontend/src/app/app-routing.module.ts
@@ -17,6 +17,16 @@ import {ImageEditComponent} from './pages/image/edit/image-edit.component';
import {ProfileComponent} from './pages/profile/profile.component';
import {OrganizationalUnitEditComponent} from './pages/organizational-unit/edit/organizational-unit-edit.component';
import {ClientComponent} from './pages/client/client.component';
+import {ClientDhcpComponent} from './pages/client/dhcp/client-dhcp.component';
+import {DeployImageCommandComponent} from './pages/command/deploy-image-command/deploy-image-command.component';
+import {MenuComponent} from './pages/menu/menu.component';
+import {MenuEditComponent} from './pages/menu/edit/menu-edit.component';
+import {SoftwareProfileComponent} from './pages/software-profile/software-profile.component';
+import {SoftwareComponentComponent} from './pages/software-component/software-component.component';
+import {SoftwareComponent} from './pages/software/software.component';
+import {LoginCommandComponent} from './pages/command/login-command/login-command.component';
+import {ExecuteCommandComponent} from './pages/command/execute-command/execute-command.component';
+import {CreateImageCommandComponent} from './pages/command/create-image-command/create-image-command.component';
const routes: Routes = [
@@ -59,14 +69,18 @@ const routes: Routes = [
},
{
path: 'clients/dhcp',
- component: ClientComponent
+ component: ClientDhcpComponent
},
{
path: 'images',
component: ImageComponent
},
{
- path: 'images/create',
+ path: 'images/create/monolithic',
+ component: ImageEditComponent
+ },
+ {
+ path: 'images/create/basic',
component: ImageEditComponent
},
{
@@ -94,10 +108,50 @@ const routes: Routes = [
component: HardwareProfileComponent
},
{
+ path: 'software',
+ component: SoftwareComponent,
+ },
+ {
+ path: 'software/profile/create',
+ component: SoftwareProfileComponent
+ },
+ {
+ path: 'software/component/create',
+ component: SoftwareComponentComponent
+ },
+ {
+ path: 'software/profile/:id',
+ component: SoftwareProfileComponent
+ },
+ {
+ path: 'menus',
+ component: MenuComponent
+ },
+ {
+ path: 'menus/create',
+ component: MenuEditComponent
+ },
+ {
path: 'commands',
component: CommandComponent
},
{
+ path: 'commands/deploy_image',
+ component: DeployImageCommandComponent
+ },
+ {
+ path: 'commands/login',
+ component: LoginCommandComponent
+ },
+ {
+ path: 'commands/execute',
+ component: ExecuteCommandComponent
+ },
+ {
+ path: 'commands/create_image',
+ component: CreateImageCommandComponent
+ },
+ {
path: 'commands/:id',
component: EditCommandComponent
},
diff --git a/admin/WebConsole3/frontend/src/app/app.module.ts b/admin/WebConsole3/frontend/src/app/app.module.ts
index 3dd55fe6..5f861c65 100644
--- a/admin/WebConsole3/frontend/src/app/app.module.ts
+++ b/admin/WebConsole3/frontend/src/app/app.module.ts
@@ -26,8 +26,8 @@ import { HardwareComponent } from './pages/hardware/hardware.component';
import { HardwareComponentsComponent } from './pages/hardware/hardware-components/hardware-components.component';
import { HardwareProfilesComponent } from './pages/hardware/hardware-profiles/hardware-profiles.component';
import { HardwareTypesComponent } from './pages/hardware/hardware-types/hardware-types.component';
-import {ProfilesTableComponent} from './pages/hardware/hardware-profiles/profiles-table/profiles-table.component';
-import {ProfilesGroupComponent} from './pages/hardware/hardware-profiles/profiles-group/profiles-group.component';
+import {HardwareProfilesTableComponent} from './pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component';
+import {HardwareProfilesGroupComponent} from './pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component';
import {HardwareComponentsTableComponent} from './pages/hardware/hardware-components/hardware-components-table/hardware-components-table.component';
import {HardwareComponentsGroupComponent} from './pages/hardware/hardware-components/hardware-components-group/hardware-components-group.component';
import {HardwareProfileComponent} from './pages/hardware-profile/hardware-profile.component';
@@ -58,6 +58,23 @@ import {OrganizationalUnitEditComponent} from './pages/organizational-unit/edit/
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {ClientComponent} from './pages/client/client.component';
import {ChartsModule} from 'ng2-charts';
+import {ClientDhcpComponent} from './pages/client/dhcp/client-dhcp.component';
+import {DeployImageCommandComponent} from './pages/command/deploy-image-command/deploy-image-command.component';
+import {MenuComponent} from './pages/menu/menu.component';
+import {MenuEditComponent} from './pages/menu/edit/menu-edit.component';
+import {SoftwareComponentComponent} from './pages/software-component/software-component.component';
+import {SoftwareComponent} from './pages/software/software.component';
+import {SoftwareComponentsComponent} from './pages/software/software-components/software-components.component';
+import {SoftwareProfilesComponent} from './pages/software/software-profiles/software-profiles.component';
+import {SoftwareProfileComponent} from './pages/software-profile/software-profile.component';
+import {SoftwareTypesComponent} from './pages/software/software-types/software-types.component';
+import {SoftwareProfilesTableComponent} from './pages/software/software-profiles/software-profiles-table/software-profiles-table.component';
+import {SoftwareProfilesGroupComponent} from './pages/software/software-profiles/software-profiles-group/software-profiles-group.component';
+import {SoftwareComponentsTableComponent} from './pages/software/software-components/software-components-table/software-components-table.component';
+import {SoftwareComponentsGroupComponent} from './pages/software/software-components/software-components-group/software-components-group.component';
+import {LoginCommandComponent} from './pages/command/login-command/login-command.component';
+import {ExecuteCommandComponent} from './pages/command/execute-command/execute-command.component';
+import {CreateImageCommandComponent} from './pages/command/create-image-command/create-image-command.component';
@@ -67,6 +84,8 @@ import {ChartsModule} from 'ng2-charts';
LoginComponent,
ImageComponent,
ImageEditComponent,
+ MenuComponent,
+ MenuEditComponent,
DashboardComponent,
RepositoryComponent,
OrganizationalUnitComponent,
@@ -79,14 +98,29 @@ import {ChartsModule} from 'ng2-charts';
HardwareProfilesComponent,
HardwareProfileComponent,
HardwareTypesComponent,
- ProfilesTableComponent,
- ProfilesGroupComponent,
+ HardwareProfilesTableComponent,
+ HardwareProfilesGroupComponent,
HardwareComponentsTableComponent,
HardwareComponentsGroupComponent,
+ SoftwareComponentComponent,
+ SoftwareComponent,
+ SoftwareComponentsComponent,
+ SoftwareProfilesComponent,
+ SoftwareProfileComponent,
+ SoftwareTypesComponent,
+ SoftwareProfilesTableComponent,
+ SoftwareProfilesGroupComponent,
+ SoftwareComponentsTableComponent,
+ SoftwareComponentsGroupComponent,
OuGroupComponent,
OuClientComponent,
ClientComponent,
+ ClientDhcpComponent,
CommandComponent,
+ DeployImageCommandComponent,
+ LoginCommandComponent,
+ ExecuteCommandComponent,
+ CreateImageCommandComponent,
EditCommandComponent,
IcheckDirective,
FixedToolboxBarDirective,
@@ -110,17 +144,28 @@ import {ChartsModule} from 'ng2-charts';
LoginComponent,
ImageComponent,
ImageEditComponent,
+ MenuComponent,
+ MenuEditComponent,
OrganizationalUnitComponent,
OrganizationalUnitEditComponent,
Ng2TableActionComponent,
- ProfilesTableComponent,
- ProfilesGroupComponent,
+ HardwareProfilesTableComponent,
+ HardwareProfilesGroupComponent,
HardwareComponentsTableComponent,
HardwareComponentsGroupComponent,
+ SoftwareProfilesTableComponent,
+ SoftwareProfilesGroupComponent,
+ SoftwareComponentsTableComponent,
+ SoftwareComponentsGroupComponent,
OuGroupComponent,
OuClientComponent,
ClientComponent,
+ ClientDhcpComponent,
CommandComponent,
+ DeployImageCommandComponent,
+ LoginCommandComponent,
+ ExecuteCommandComponent,
+ CreateImageCommandComponent,
EditCommandComponent,
OgOuGeneralOptionsComponent,
TraceComponent,
diff --git a/admin/WebConsole3/frontend/src/app/form-type/menu.form-type.ts b/admin/WebConsole3/frontend/src/app/form-type/menu.form-type.ts
new file mode 100644
index 00000000..94a8d97b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/form-type/menu.form-type.ts
@@ -0,0 +1,12 @@
+import {GlobunetFormType} from './globunet.form-type';
+import {Menu} from '../model/menu';
+
+
+export class MenuFormType extends GlobunetFormType {
+ getForm() {
+ const form: any[] = GlobunetFormType.getForm(new Menu());
+ this.setFieldType(form, 'description', 'textarea');
+ this.setFieldType(form, 'resolution', 'select');
+ return form;
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/model/command.ts b/admin/WebConsole3/frontend/src/app/model/command.ts
index 2f3639ba..2c5697aa 100644
--- a/admin/WebConsole3/frontend/src/app/model/command.ts
+++ b/admin/WebConsole3/frontend/src/app/model/command.ts
@@ -1,8 +1,14 @@
-import { Resource } from 'globunet-angular/core/models/api/resource';
-
-export class Command extends Resource {
- public title = '';
- public script = '';
- public parameters = false;
-
-}
+import { Resource } from 'globunet-angular/core/models/api/resource';
+
+export class Excecution {
+ script = '';
+ clients = '';
+ type = '';
+}
+
+export class Command extends Resource {
+ public title = '';
+ public script = '';
+ public parameters = false;
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/model/image.ts b/admin/WebConsole3/frontend/src/app/model/image.ts
index 2a85299f..2d52cf63 100644
--- a/admin/WebConsole3/frontend/src/app/model/image.ts
+++ b/admin/WebConsole3/frontend/src/app/model/image.ts
@@ -1,20 +1,24 @@
-import { Resource } from 'globunet-angular/core/models/api/resource';
-import {Repository} from './repository';
-
-export class PartitionInfo {
- numDisk: number;
- numPartition: number;
- partitionCode: string;
- filesystem: string;
- osName: string;
-}
-
-export class Image extends Resource {
- public canonicalName: string = '';
- public repository: Repository = new Repository();
- public description: string = '';
- public comments: string = '';
- public revision: string;
- public createdAt: Date;
- public partitionInfo: PartitionInfo;
-}
+import { Resource } from 'globunet-angular/core/models/api/resource';
+import {Repository} from './repository';
+import {Client} from './client';
+import {SoftwareProfile} from './software-profile';
+
+export class PartitionInfo {
+ numDisk: number;
+ numPartition: number;
+ partitionCode: string;
+ filesystem: string;
+ osName: string;
+}
+
+export class Image extends Resource {
+ public canonicalName = '';
+ public repository: Repository = new Repository();
+ public description = '';
+ public comments = '';
+ public revision: string;
+ public createdAt: Date;
+ public softwareProfile: SoftwareProfile;
+ public partitionInfo: PartitionInfo;
+ public client?: Client;
+}
diff --git a/admin/WebConsole3/frontend/src/app/model/menu.ts b/admin/WebConsole3/frontend/src/app/model/menu.ts
index e8928976..1d19bd44 100644
--- a/admin/WebConsole3/frontend/src/app/model/menu.ts
+++ b/admin/WebConsole3/frontend/src/app/model/menu.ts
@@ -1,12 +1,12 @@
-import { Resource } from 'globunet-angular/core/models/api/resource';
-
-export class Menu extends Resource {
- public title: string;
- public resolution: string;
- public description: string;
- public comments: string;
- public publicColumns: number;
- public publicUrl: string;
- public privateColumns: number;
- public privateUrl: string;
-}
+import { Resource } from 'globunet-angular/core/models/api/resource';
+
+export class Menu extends Resource {
+ public title = '';
+ public resolution = '';
+ public description = '';
+ public comments = '';
+ public publicUrl = ''
+ public privateUrl = '';
+ public publicColumns: number;
+ public privateColumns: number;
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html
new file mode 100644
index 00000000..c21f5c8d
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html
@@ -0,0 +1,139 @@
+<section class="content-header">
+ <h1 translate="dhcp_clients">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
+ <li><a [routerLink]="'app/ous'" ><i class="fa fa-th"></i> {{'ous'|translate}}</a></li>
+ <li class="active" translate="dhcp_clients"></li>
+ </ol>
+</section>
+<section fixed-toolboxbar class="toolboxbar">
+ <div>
+ <div class="col-md-12">
+ <div class="box-tools pull-right">
+ <button class="btn btn-primary" translate="save" (click)="save()"></button>
+ </div>
+ </div>
+ </div>
+</section>
+<section class="content">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box box-primary">
+ <div class="box-header with-border">
+ <h3 class="box-title" translate="load_clients_from_dhcp"></h3>
+ <div *ngIf="clients.length == 0" class="btn-group pull-right">
+ <button type="button" name="search" id="search-btn" class="btn btn-flat" (click)="downloadFromServer()">
+ <i class="fa fa-download"></i>
+ <span translate="download_from_server"></span>
+ </button>
+ <button class="btn btn-primary" (click)="proccessDhcp()" translate="proccess_dhcp"></button>
+ </div>
+ <div *ngIf="clients.length > 0" class="pull-right">
+ <button class="btn btn-danger" (click)="clients = []" translate="back"></button>
+ </div>
+ </div>
+ <div *ngIf="clients.length == 0" class="box-body">
+ <div class="row">
+ <div class="col-md-12">
+ <textarea [(ngModel)]="dhcpText" class="og-instructions">
+
+ </textarea>
+ </div>
+ </div>
+ </div>
+ <div class="box-body" *ngIf="clients.length > 0">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box box-default">
+ <div class="box-header with-border">
+ <h3 class="box-title" translate="common_options"></h3>
+ </div>
+ <div class="box-body">
+ <div class="row">
+ <div class="col-xs-2">
+ <div class="form-group">
+ <label class="control-label" for="repository" translate="repository"></label>
+ <select name="repository" class="form-control" [(ngModel)]="commonProperties.repository">
+ <option *ngFor="let repository of repositories" [value]="repository.id">{{repository.name}}</option>
+ </select>
+ </div>
+ </div>
+ <div class="col-xs-2">
+ <div class="form-group">
+ <label class="control-label" for="hardwareProfile" translate="hardware_profile"></label>
+ <select name="hardwareProfile" class="form-control" [(ngModel)]="commonProperties.hardwareProfile">
+ <option *ngFor="let profile of hardwareProfiles" [value]="profile.id">
+ {{profile.description}}
+ </option>
+ </select>
+ </div>
+ </div>
+ <div class="col-xs-1">
+ <div class="form-group">
+ <label class="control-label" for="netiface" translate="netiface"></label>
+ <input type="text" name="netiface" class="form-control" [(ngModel)]="commonProperties.netiface" />
+ </div>
+ </div>
+ <div class="col-xs-2">
+ <div class="form-group">
+ <label class="control-label" for="netdriver" translate="netdriver"></label>
+ <input type="text" name="netdriver" class="form-control" [(ngModel)]="commonProperties.netdriver" />
+ </div>
+ </div>
+ <div class="form-group col-md-3">
+ <label for="oglive" translate="oglive">
+ <span class="symbol required ng-scope"></span>
+ </label>
+ <select class="form-control" required="true" [(ngModel)]="commonProperties.oglive" name="oglive">
+ <option *ngFor="let item of constants.ogliveinfo" [value]="item.directory">
+ {{item.directory}}
+ </option>
+ </select>
+ </div>
+ <div class="form-group col-md-2">
+ <label for="netboot" translate="netboot">
+ <span class="symbol required ng-scope"></span>
+ </label>
+ <select class="form-control" required="true" [(ngModel)]="commonProperties.netboot" name="netboot">
+ <option *ngFor="let item of netboots" [value]="item.id">{{item.name}}</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <!-- /.box-body -->
+ </div>
+ </div>
+ <div class="col-md-12">
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th>
+ <input icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" (change)="selectedUnselectAll()" [(ngModel)]="selectAll" />
+ <span translate="select"></span>
+ </th>
+ <th translate="name"></th>
+ <th translate="ip"></th>
+ <th translate="mac"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr *ngFor="let client of clients">
+ <td>
+ <input icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" [(ngModel)]="client.$$selected" />
+ </td>
+ <td>{{client.name}}</td>
+ <td>{{client.ip}}</td>
+ <td>{{client.mac}}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="box-footer">
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.scss b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.scss
new file mode 100644
index 00000000..0bbea7e4
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.scss
@@ -0,0 +1,5 @@
+::ng-deep app-client {
+ ::ng-deep .box-title {
+ width: 100%;
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts
new file mode 100644
index 00000000..70394ba4
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts
@@ -0,0 +1,223 @@
+import {Component, OnInit} from '@angular/core';
+
+import {ClientService} from 'src/app/api/client.service';
+import {ActivatedRoute, ParamMap, Router} from '@angular/router';
+import {forkJoin, Observable} from 'rxjs';
+import {NetbootService} from '../../../api/netboot.service';
+import {ToasterService} from '../../../service/toaster.service';
+import {RepositoryService} from '../../../api/repository.service';
+import {HardwareProfileService} from '../../../api/hardware-profile.service';
+import {Repository} from '../../../model/repository';
+import {HardwareProfile} from '../../../model/hardware-profile';
+import {OgCommonService} from '../../../service/og-common.service';
+import {ClientFormType} from '../../../form-type/client.form-type';
+import {TranslateService} from '@ngx-translate/core';
+
+@Component({
+ selector: 'app-client-dhcp',
+ templateUrl: './client-dhcp.component.html',
+ styleUrls: ['./client-dhcp.component.scss']
+})
+export class ClientDhcpComponent implements OnInit {
+ public netboots: any = [];
+ public repositories: Repository[] = [];
+ public hardwareProfiles: HardwareProfile[] = [];
+ public oglives: any[] = [];
+ private formType: ClientFormType;
+ public form;
+ public constants = {};
+ private dhcpFile: string;
+ public commonProperties: any;
+ public dhcpText: string;
+ public clients: any[];
+ public selectAll: boolean;
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(private router: Router,
+ private activatedRouter: ActivatedRoute,
+ private clientService: ClientService,
+ private netbootService: NetbootService,
+ private translate: TranslateService,
+ private toaster: ToasterService,
+ private repositoryService: RepositoryService,
+ private hardwareProfileService: HardwareProfileService,
+ private ogCommonService: OgCommonService) {
+
+ this.commonProperties = {};
+ this.clients = [];
+
+ }
+
+ ngOnInit() {
+ this.ogCommonService.loadEngineConfig().subscribe(
+ data => {
+ this.constants = data.constants;
+ }
+ );
+ this.dhcpFile = '/etc/dhcp/dhcpd.conf';
+ this.loadNetboots();
+ // Los repositorios vienen cargados ya desde config.router
+ this.repositoryService.list().subscribe(
+ (repositories) => {
+ this.repositories = repositories;
+ this.commonProperties.repository = this.repositories[0].id;
+ if (!this.hardwareProfiles) {
+ this.hardwareProfileService.list().subscribe(
+ (response) => {
+ this.hardwareProfiles = response;
+ this.commonProperties.hardwareProfile = this.hardwareProfiles[0].id;
+ },
+ (error) => {
+ alert(error);
+ }
+ );
+ } else {
+ this.hardwareProfiles = this.hardwareProfiles;
+ }
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+
+ }
+
+ loadNetboots() {
+ this.netbootService.list().subscribe(
+ (result) => {
+ this.netboots = result;
+ this.commonProperties.netboot = this.netboots[0];
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+
+
+ downloadFromServer() {
+ this.dhcpText = 'ddns-update-style none;\n' +
+ 'option domain-name "example.org";\n' +
+ 'log-facility local7;\n' +
+ 'not-authoritative;\n' +
+ '\n' +
+ 'subnet 172.16.140.0 netmask 255.255.255.0 {\n' +
+ ' option domain-name-servers 172.16.3.1;\n' +
+ ' option routers 172.16.140.254;\n' +
+ ' option broadcast-address 172.16.140.255;\n' +
+ ' default-lease-time 600;\n' +
+ ' max-lease-time 7200;\n' +
+ ' next-server 172.16.140.210;\n' +
+ ' filename "grldr";\n' +
+ ' use-host-decl-names on;\n' +
+ '\n' +
+ '# host HOSTNAME1 {\n' +
+ '# hardware ethernet HOSTMAC1;\n' +
+ '# fixed-address HOSTIP1;\n' +
+ '# }\n' +
+ '\n' +
+ ' host pc-pruebas {\n' +
+ ' hardware ethernet 00:1B:21:1F:EE:9D;\n' +
+ ' fixed-address 172.16.140.213;\n' +
+ ' }\n' +
+ ' host pc-virtualbox {\n' +
+ ' hardware ethernet 20:CF:30:BF:9A:39;\n' +
+ ' fixed-address 172.16.140.214;\n' +
+ ' }\n' +
+ '\n' +
+ '\n' +
+ '}\n';
+ /*
+ ServerDchpResource.getDhcp().then(
+ function(response) {
+ this.dhcpText = response.text;
+ this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_loaded')});
+ },
+ function(error) {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ /**/
+ }
+
+ proccessDhcp() {
+ if (typeof this.dhcpText !== 'undefined' && this.dhcpText !== '') {
+ const lines = this.dhcpText.split('\n');
+ this.clients = [];
+ for (let i = 0; i < lines.length; i++) {
+ // Comprobar si la línea actual contiene la palabra "host" sin ninguna # delante que sería comentario
+ if (/^host/.test(lines[i].trim())) {
+ // Unimos las siguientes líneas hasta encontrar "}"
+ let line = '';
+ while(lines[i].indexOf("}") === -1 && i < lines.length){
+ line += lines[i];
+ i++;
+ }
+ // procesar la linea
+ // host pc53-151 { hardware ethernet 00:1E:33:61:49:B8; fixed-address 172.16.53.151; }
+ let parts = line.split('{');
+ const hostname = parts[0].trim().split(' ')[1];
+
+ // Las siguientes partes pueden estar en la linea actual o las siguientes
+ parts = parts[1].trim().split(";");
+ const mac = parts[0].trim().split('ethernet')[1];
+ // lo mismo puede ocurrir con fixed-address puede estar en lineas diferentes
+ parts = parts[1].trim().split('fixed-address');
+ const ip = parts[1];
+ this.clients.push(
+ {
+ name: hostname,
+ ip: ip,
+ mac: mac,
+ $$selected: true
+ }
+ );
+ }
+ }
+ } else {
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('nothing_to_proccess')});
+ }
+ }
+
+ selectedUnselectAll() {
+ for (let c = 0; c < this.clients.length; c++) {
+ this.clients[c].$$selected = this.selectAll;
+ }
+ }
+
+ save() {
+ const promises = [];
+ let ou = '';
+ this.activatedRouter.queryParams.subscribe(
+ query => {
+ ou = query.ou;
+ }
+ );
+ for (let c = 0; c < this.clients.length; c++) {
+ if (this.clients[c].$$selected === true) {
+ const client = Object.assign({}, this.clients[c]);
+
+ // Si se indicó un padre en la url, se añade dicha propiedad
+ client.organizationalUnit = ou;
+ client.idproautoexec = 0;
+ client.netdriver = this.commonProperties.netdriver;
+ client.netiface = this.commonProperties.netiface;
+ // Propiedades comunes
+ // client.repository = this.commonProperties.repository;
+ // client.hardwareProfile = this.commonProperties.hardwareProfile;
+ promises.push(this.clientService.create(client));
+ }
+ }
+ forkJoin(promises).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: 'success', body: 'Successfully saved'});
+ this.router.navigate(['/app/ous']);
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.html b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.html
new file mode 100644
index 00000000..9534718c
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.html
@@ -0,0 +1,98 @@
+<section class="content-header">
+ <h1 translate="create_image">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'/app/dashboard'"><i class="fa fa-dashboard"></i>{{'dashboard'|translate}}</a></li>
+ <li><a [routerLink]="'/app/ous'"><i class="fa fa-th"></i>{{'ous'|translate}}</a></li>
+ <li class="active" translate="create_image"></li>
+ </ol>
+</section>
+<section fixed-toolboxbar class="toolboxbar">
+ <div>
+ <div class="col-md-12">
+ <div class="box-tools pull-right">
+ <button class="btn btn-primary" translate="execute" (click)="sendCommand()"></button>
+ </div>
+ </div>
+ </div>
+</section>
+<section style="padding: 0 30px;">
+ <h3 translate="selected_clients"></h3>
+ <app-og-selected-clients></app-og-selected-clients>
+</section>
+<!-- Main content -->
+<section class="content">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box box-primary">
+ <div class="box-header with-border">
+ </div>
+ <div class="box-body">
+ <form role="form" name="Form">
+ <div class="form-group">
+ <label>
+ <span translate="client"></span>
+ {{client.name}}
+ </label>
+ </div>
+ <div class="form-group" ng-class="{'has-error':Form.images.$dirty && Form.images.$invalid, 'has-success':Form.images.$valid}">
+ <label for="images">
+ <span translate="images"></span>
+ </label>
+ <select (change)="setCanonicalName()" class="form-control" type="text" [(ngModel)]="command.image" name="images">
+ <option [ngValue]="null" translate="----"></option>
+ <option *ngFor="let image of images" [ngValue]="image">{{image.canonicalName}}</option>
+ </select>
+ </div>
+ <div class="form-group" ng-class="{'has-error':Form.canonicalName.$dirty && Form.canonicalName.$invalid, 'has-success':Form.canonicalName.$valid}">
+ <label for="canonicalName">
+ <span translate="canonicalName"></span>
+ <span class="symbol required"></span>
+ </label>
+ <input type="text" class="form-control" type="text" required="true" [(ngModel)]="command.canonicalName" name="canonicalName">
+ </div>
+ <div>
+ <table class="table">
+ <thead>
+ <tr>
+ <th translate="select">
+ </th>
+ <th translate="disk">
+ </th>
+ <th translate="partition">
+ </th>
+ <th translate="filesystem">
+ </th>
+ <th translate="osname">
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <ng-container *ngFor="let partition of client.partitions; let index = index;">
+ <tr *ngIf="isClonable(partition)">
+ <td>
+ <input icheck type="radio" [name]="'partition_'+partition.numPartition" checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" class="selection-checkbox" [(ngModel)]="selectedPartition" [value]="index" />
+ </td>
+ <td>
+ {{partition.numDisk}}
+ </td>
+ <td>
+ {{partition.numPartition}}
+ </td>
+ <td>
+ {{partition.filesystem}}
+ </td>
+ <td>
+ {{partition.osName}}
+ </td>
+ </tr>
+ </ng-container>
+ </tbody>
+ </table>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.scss b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.scss
new file mode 100644
index 00000000..08b1082b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.scss
@@ -0,0 +1,3 @@
+app-execute-command {
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts
new file mode 100644
index 00000000..8f018e33
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/create-image-command/create-image-command.component.ts
@@ -0,0 +1,188 @@
+import {Component, OnInit} from '@angular/core';
+
+import {ToasterService} from '../../../service/toaster.service';
+import {ActivatedRoute, Router} from '@angular/router';
+import {TranslateService} from '@ngx-translate/core';
+import {OgCommonService} from '../../../service/og-common.service';
+import {OgSweetAlertService} from '../../../service/og-sweet-alert.service';
+import {AuthModule} from 'globunet-angular/core';
+import {User} from '../../../model/user';
+import {OGCommandsService} from '../../../service/og-commands.service';
+import {CommandService} from '../../../api/command.service';
+import {Image} from '../../../model/image';
+import {Command, Excecution} from '../../../model/command';
+import {Client, Partition} from '../../../model/client';
+import {Repository} from '../../../model/repository';
+import {RepositoryService} from '../../../api/repository.service';
+import {ImageService} from '../../../api/image.service';
+import {forkJoin} from 'rxjs';
+
+@Component({
+ selector: 'app-create-image-command',
+ templateUrl: './create-image-command.component.html',
+ styleUrls: [ './create-image-command.component.scss' ]
+})
+export class CreateImageCommandComponent implements OnInit {
+ private readonly user: User;
+ private constants: any;
+ public repositories: Repository[];
+ public execution = new Excecution();
+ public commands: Command[] = [];
+ public client: Client;
+ public images = [];
+ public command = {canonicalName: '', image: new Image()};
+ public selectedPartition: number;
+
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(public ogCommandsService: OGCommandsService,
+ private authModule: AuthModule,
+ private router: Router,
+ private activatedRoute: ActivatedRoute,
+ private ogCommonService: OgCommonService,
+ private commandService: CommandService,
+ private imageService: ImageService,
+ private repositoryService: RepositoryService,
+ private ogSweetAlert: OgSweetAlertService,
+ private toaster: ToasterService,
+ private translate: TranslateService) {
+ this.user = this.authModule.getLoggedUser();
+ }
+
+
+
+ ngOnInit() {
+ if (this.user && this.ogCommonService.selectedClients) {
+ const clientId = Object.keys(this.ogCommonService.selectedClients)[0];
+ this.client = this.ogCommonService.selectedClients[clientId];
+ this.execution.clients = clientId;
+ this.ogCommonService.loadEngineConfig().subscribe(
+ data => {
+ this.constants = data.constants;
+ }
+ );
+ this.loadRepositories();
+ this.loadImages();
+ } else {
+ // TODO - dar error?
+ this.ogSweetAlert.error(this.translate.instant('opengnsys_error'), this.translate.instant('not_clients_selected'));
+ this.router.navigate(['app.ous']);
+ }
+ }
+
+
+ sendCommand() {
+ if (!this.selectedPartition) {
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('you_must_select_partition')});
+ } else {
+ const disk = this.client.partitions[this.selectedPartition].numDisk;
+ const partition = this.client.partitions[this.selectedPartition].numPartition;
+ // Al crear la imagen, le asociamos un perfil software
+ // @ts-ignore
+ this.execution.script = this.constants.commands.SOFTWARE_INVENTORY + ' ' + disk + ' ' + partition + '\n';
+ this.execution.script += this.constants.commands.CREATE_IMAGE + ' ' + disk + ' ' + partition + ' ' + this.command.canonicalName + ' REPO ';
+ // @ts-ignore
+ this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$');
+
+ let image: Image = this.command.image;
+ let newImage = false;
+
+ let result = true;
+ // Crear la imagen si no existe
+ if (!image) {
+ newImage = true;
+ // Comprobar que exista el repositorio, sino no podemos crear la nueva imagen
+ if (!this.repositories) {
+ result = false;
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('no_repository_exist')});
+ } else {
+ // Usar el repositorio por defecto
+ const repository = this.repositories[0];
+ image = new Image();
+ image.canonicalName = this.command.canonicalName;
+ image.description = this.translate.instant('image_created_automatically');
+ image.repository = repository;
+ }
+ }
+
+ // Asignar a la imagen los atributos del sistema operativo elegido
+ image.client = this.client;
+
+ // Si no hubo ningun error se guardan todas las pgms
+ if (result === true) {
+ const promises = [];
+ if (newImage === true) {
+ promises.push(this.imageService.create(image));
+ } else {
+ const imageCopy = Object.assign({}, image);
+ delete imageCopy.id;
+ delete imageCopy.softwareProfile;
+ promises.push(this.imageService.update(imageCopy));
+ }
+ this.execution.type = 'CREATE_IMAGE';
+ promises.push(this.commandService.execute(this.execution));
+ forkJoin(promises).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_executed')});
+ this.router.navigate(['app.ous']);
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ }
+ }
+
+ setCanonicalName() {
+ if (this.command.image !== null) {
+ this.command.canonicalName = this.command.image.canonicalName;
+ } else {
+ this.command.canonicalName = '';
+ }
+ }
+
+ private loadImages() {
+ this.imageService.list().subscribe(
+ (response) => {
+ this.images = response;
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ private loadRepositories() {
+ this.repositoryService.list().subscribe(
+ (response) => {
+ this.repositories = response;
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+
+ isClonable(partition) {
+ let clonable = false;
+ let index = 0;
+ const code = partition.partitionCode;
+
+ if (partition.numPartition !== 0) {
+ // Buscar el codigo entre las constantes
+ while (index < this.constants.partitiontable.length && !clonable) {
+ // para cada tabla de particiones, buscamos el codigo de la particion
+ const elements = this.constants.partitiontable[index].partitions.filter(function(part) {
+ return (part.id === partition.partitionCode.padStart(2, '0'));
+ }
+ );
+ clonable = (elements.length > 0 && elements[0].clonable === true);
+ index++;
+ }
+ }
+
+ return clonable;
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.html b/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.html
new file mode 100644
index 00000000..7dc55c29
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.html
@@ -0,0 +1,146 @@
+<section class="content-header">
+ <h1 translate="deploy_image"></h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'/app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
+ <li><a [routerLink]="'/app/ous'" ><i class="fa fa-th"></i> {{'ous'|translate}}</a></li>
+ <li class="active" translate="deploy_image"></li>
+ </ol>
+</section>
+<section style="padding: 0 30px;">
+ <h3 translate="selected_clients"></h3>
+ <app-og-selected-clients></app-og-selected-clients>
+</section>
+<section class="content padding-top-30" style="padding-top: 30px">
+ <div class="box box-default box-solid">
+ <div class="box-header with-border">
+ </div>
+ <!-- /.box-header -->
+ <div class="box-body">
+ <form role="form" name="Form">
+ <div class="row">
+ <div class="form-group col-md-3" >
+ <div class="checkbox clip-check check-primary checkbox-inline">
+ <input id="deployImageParameters" name="deployImage" icheck checkbox-class="iradio_square-blue" radio-class="iradio_square-blue" type="radio" class="selection-checkbox" value="true" [(ngModel)]="deployImage" (change)="updateDeployOptions()" />
+ </div>
+ <label for="deployImage">
+ <span translate="deploy_image_update_restore"></span>
+ </label>
+ </div>
+ <div class="form-group col-md-3">
+ <div class="checkbox clip-check check-primary checkbox-inline">
+ <input id="parameters" name="updateCache" icheck checkbox-class="iradio_square-blue" radio-class="iradio_square-blue" type="radio" class="selection-checkbox" value="false" [(ngModel)]="deployImage" (change)="updateDeployOptions()" />
+ </div>
+ <label for="updateCache">
+ <span translate="update_cache_only_download"></span>
+ </label>
+ </div>
+ </div>
+ <div class="row">
+ <div class="form-group col-md-4">
+ <div class="form-group" ng-class="{'has-error':Form.images.$dirty && Form.images.$invalid, 'has-success':Form.images.$valid}">
+ <label>
+ <span translate="images"></span>
+ </label>
+ <select (change)="setCanonicalName()" class="form-control" type="text" [(ngModel)]="image" name="images">
+ <option *ngFor="let image of images" [ngValue]="image">{{image.canonicalName}}</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group col-md-2">
+ <label for="disk" translate="disk">
+ </label>
+ <input name="disk" type="number" min="1" [(ngModel)]="disk" class="form-control">
+
+ </div>
+ <div class="form-group col-md-2">
+ <label for="partition" translate="partition">
+ </label>
+ <input name="partition" type="number" min="1" [(ngModel)]="partition" class="form-control">
+ </div>
+ <div class="form-group col-md-4">
+ <label for="deployMethod" translate="deploy_method">
+ </label>
+ <select class="form-control" name="deployMethod" [(ngModel)]="deployMethod">
+ <option *ngFor="let deployMethod of deployMethods" [value]="deployMethod">{{deployMethod}}</option>
+ </select>
+ </div>
+ </div>
+ <div *ngIf="deployMethod == 'MULTICAST' || deployMethod == 'MULTICAST-DIRECT'">
+ <div class="row">
+ <div class="form-group col-md-4">
+ <label for="port" translate="port">
+ </label>
+ <input class="form-control" type="text" name="port" [(ngModel)]="multicast.port"/>
+ </div>
+ <div class="form-group col-md-4">
+ <label for="address" translate="address">
+ </label>
+ <input class="form-control" type="text" name="address" [(ngModel)]="multicast.address"/>
+ </div>
+ <div class="form-group col-md-4">
+ <label for="multicastMode" translate="mode">
+ </label>
+ <input class="form-control" type="text" name="multicastMode" [(ngModel)]="multicast.mode"/>
+ </div>
+ </div>
+ <div class="row">
+ <div class="form-group col-md-4">
+ <label for="speed" translate="speed">
+ </label>
+ <input class="form-control" type="text" name="speed" [(ngModel)]="multicast.speed"/>
+ </div>
+ <div class="form-group col-md-4">
+ <label for="maxClients" translate="max_clients">
+ </label>
+ <input class="form-control" type="text" name="maxClients" [(ngModel)]="multicast.maxClients"/>
+ </div>
+ <div class="form-group col-md-4">
+ <label for="maxWaitTime" translate="max_wait_time">
+ </label>
+ <input class="form-control" type="text" name="maxWaitTime" [(ngModel)]="multicast.maxWaitTime"/>
+ </div>
+ </div>
+ </div>
+ <div class="row" *ngIf="deployMethod == 'TORRENT'">
+ <div class="form-group col-md-6">
+ <label for="torrentMode" translate="mode">
+ </label>
+ <input class="form-control" type="text" name="torrentMode" [(ngModel)]="torrent.mode"/>
+ </div>
+ <div class="form-group col-md-6">
+ <label for="seedTime" translate="seed_time">
+
+ </label>
+ <input class="form-control" type="text" name="seedTime" [(ngModel)]="torrent.seedTime"/>
+ </div>
+ </div>
+ </form>
+
+ </div>
+ <!-- /.box-body -->
+ <div class="box-footer">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="btn-group pull-left">
+ <button class="btn btn-primary"(click)="generateOgInstruction()"><span translate="generate_og_instruction"></span></button>
+ <button [class]="editInstructions == false ? 'btn btn-default':'btn btn-success'" *ngIf="ogCommandsService.ogInstructions != ''" (click)="editInstructions = !editInstructions"><span translate="{{editInstructions == false?'edit':'done'}}"></span></button>
+ </div>
+ <div class="btn-group pull-right">
+ <app-og-execute-command-options></app-og-execute-command-options>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box">
+ <div class="box-header"></div>
+ <div class="box-body" >
+ <div *ngIf="editInstructions == false" [innerHTML]="ogCommandsService.ogInstructions|ogCommands"></div>
+ <textarea *ngIf="editInstructions == true" class="og-instructions" [(ngModel)]="ogCommandsService.ogInstructions"></textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.scss b/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.scss
new file mode 100644
index 00000000..ccb34440
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.scss
@@ -0,0 +1,3 @@
+command {
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.ts
new file mode 100644
index 00000000..b8312964
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/deploy-image-command/deploy-image-command.component.ts
@@ -0,0 +1,137 @@
+import {Component, OnInit} from '@angular/core';
+
+import {ToasterService} from '../../../service/toaster.service';
+import {ActivatedRoute, Router} from '@angular/router';
+import {TranslateService} from '@ngx-translate/core';
+import {OgCommonService} from '../../../service/og-common.service';
+import {OgSweetAlertService} from '../../../service/og-sweet-alert.service';
+import {AuthModule} from 'globunet-angular/core';
+import {User} from '../../../model/user';
+import {ImageService} from '../../../api/image.service';
+import {OGCommandsService} from '../../../service/og-commands.service';
+
+@Component({
+ selector: 'app-deploy-image-command',
+ templateUrl: './deploy-image-command.component.html',
+ styleUrls: [ './deploy-image-command.component.scss' ]
+})
+export class DeployImageCommandComponent implements OnInit {
+ torrent = {
+ mode: 'peer',
+ seedTime: '60'
+ };
+ multicast = {
+ port: '9000',
+ address: '239.194.16.140',
+ mode: 'full-duplex',
+ speed: 90,
+ maxClients: 50,
+ maxWaitTime: 60
+ };
+ disk = 1;
+ partition = 1;
+
+ images = [];
+ deployMethods = [];
+ deployMethod = 'MULTICAST';
+ private deployImage: string;
+ private user: User;
+ private constants: any;
+ public image: any;
+ public editInstructions = false;
+
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(public ogCommandsService: OGCommandsService,
+ private authModule: AuthModule,
+ private router: Router,
+ private activatedRoute: ActivatedRoute,
+ private ogCommonService: OgCommonService,
+ private imageService: ImageService,
+ private ogSweetAlert: OgSweetAlertService,
+ private toaster: ToasterService,
+ private translate: TranslateService) {
+ this.user = this.authModule.getLoggedUser();
+ }
+
+
+ ngOnInit() {
+ this.deployImage = 'true';
+ this.updateDeployOptions();
+ if (this.user) {
+ // Comprobar la selección de clientes
+ if (this.ogCommonService.getSelectionSize() > 0) {
+ this.imageService.list().subscribe(
+ (response) => {
+ this.images = response;
+ },
+ (error) => {
+ this.images = [];
+
+ }
+ );
+
+ } else {
+ // TODO - dar error?
+ this.toaster.pop({type: 'error', body: this.translate.instant('not_clients_selected'), title: this.translate.instant('opengnsys_error')});
+ this.router.navigate(['app.ous']);
+ }
+ }
+ }
+
+ updateDeployOptions() {
+ this.ogCommonService.loadEngineConfig().subscribe(
+ data => {
+ this.constants = data.constants;
+ if (this.deployImage === 'true') {
+ this.deployMethods = this.constants.deployMethods.deployImage;
+ } else {
+ // Si es updateCache, se quitan las opciones de deploy direct
+ this.deployMethods = this.constants.deployMethods.updateCache;
+ }
+ }
+ );
+
+ }
+
+ /**/
+ generateOgInstruction() {
+ let script = '';
+ const disk = this.disk;
+ const partition = this.partition;
+ // Capturar ip del repositorio de la imagen elegida
+ let ip = '172.16.140.210';
+ let imgName = this.image.canonicalName;
+ let target = ' ' + disk + ' ' + partition;
+ let log = 'ogEcho log session "[0] $MSG_SCRIPTS_TASK_START ';
+
+ // Modo deploy
+ if (this.deployImage === 'true') {
+ script = 'deployImage ';
+ } else {
+ script = 'updateCache ';
+ ip = 'REPO';
+ imgName += '.img';
+ target = '';
+ }
+ script += ip + ' /' + imgName + target + ' ' + this.deployMethod;
+ log += script + '"\n';
+ script = log + script;
+
+ // Modo
+ let params = '';
+ if (this.deployMethod === 'MULTICAST' || this.deployMethod === 'MULTICAST-DIRECT') {
+ params = this.multicast.port + ':' + this.multicast.mode + ':' + this.multicast.address + ':' + this.multicast.speed + 'M:' + this.multicast.maxClients + ':' + this.multicast.maxWaitTime;
+ } else if (this.deployMethod === 'TORRENT') {
+ params = this.torrent.mode + ':' + this.torrent.seedTime;
+ }
+ script += ' ' + params;
+
+ this.ogCommandsService.ogInstructions = script;
+ }
+
+ setCanonicalName() {
+ //this.command.canonicalName = this.command.image.canonicalName;
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.html b/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.html
new file mode 100644
index 00000000..37d7f8e2
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.html
@@ -0,0 +1,95 @@
+<section class="content-header">
+ <h1 translate="new_command">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'/app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
+ <li><a [routerLink]="'/app/commands'"><i class="fa fa-terminal"></i> {{'commands'|translate}}</a></li>
+ <li class="active" translate="command"></li>
+ </ol>
+</section>
+<section style="padding: 0 30px;">
+ <h3 translate="selected_clients"></h3>
+ <app-og-selected-clients></app-og-selected-clients>
+</section>
+<section fixed-toolboxbar class="toolboxbar">
+ <div>
+ <div class="col-md-12">
+ <app-og-execute-command-options></app-og-execute-command-options>
+ </div>
+ </div>
+</section>
+<!-- Main content -->
+<section class="content">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box box-primary">
+ <div class="box-header with-border">
+ <div class="form-inline">
+ <div class="form-group" ng-class="{'has-error':Form.newCommand.$dirty && Form.newCommand.$invalid, 'has-success':Form.newCommand.$valid}">
+ <div class="checkbox clip-check check-primary checkbox-inline">
+ <input id="parameters" name="newCommand" icheck checkbox-class="iradio_square-blue" radio-class="iradio_square-blue" type="radio" class="selection-checkbox" value="true" [(ngModel)]="newCommand" />
+ </div>
+ <label for="newCommand">
+ <span translate="new_command"></span>
+ </label>
+ </div>
+ <div class="form-group" ng-class="{'has-error':Form.savedCommand.$dirty && Form.savedCommand.$invalid, 'has-success':Form.savedCommand.$valid}">
+ <div class="checkbox clip-check check-primary checkbox-inline">
+ <input id="parameters" name="savedCommand" icheck checkbox-class="iradio_square-blue" radio-class="iradio_square-blue" type="radio" class="selection-checkbox" value="false" [(ngModel)]="newCommand" />
+ </div>
+ <label for="savedCommand">
+ <span translate="saved_command"></span>
+ </label>
+ </div>
+ </div>
+ </div>
+ <div class="box-body">
+ <form role="form" name="Form" *ngIf="newCommand == 'true'">
+ <div class="form-group" ng-class="{'has-error':Form.script.$dirty && Form.script.$invalid, 'has-success':Form.script.$valid}">
+ <label for="script">
+ <span translate="script"></span>
+ <span *ngIf="required == 'true'" class="symbol required"></span>
+ </label>
+ <textarea class="form-control" class="og-instructions" type="text" required="true" [(ngModel)]="ogCommandsService.ogInstructions" name="script"></textarea>
+ </div>
+ </form>
+ <form role="form" name="Form" *ngIf="newCommand == 'false'">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="form-group">
+ <label translate="commands"></label>
+ <select class="form-control" name="command" [(ngModel)]="selectedCommand" (change)="updateSelectedCommand()">
+ <option *ngFor="let command of commands" [ngValue]="command">{{command.title}}</option>
+ </select>
+ </div>
+ <div class="form-group" *ngIf="selectedCommand.parameters == true">
+ <label translate="parameters"></label>
+ <p class="help-block"><span translate="detected_params"></span> <span style="font-weight: bold" ng-bind-html="selectedCommand.inputs.length"></span></p>
+ <div class="row">
+ <div class="col-md-2" *ngFor="let input of selectedCommand.inputs; let index = index">
+ <label for="param{{index}}">
+ <span translate="parameter"></span> {{index+1}}
+ </label>
+ <input type="text" name="param{{index}}" [value]="selectedCommand.inputs[index]" (change)="updateScript(index, $event)">
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box">
+ <div class="box-header"></div>
+ <div class="box-body" >
+ <div *ngIf="editInstructions == false" [innerHTML]="ogCommandsService.ogInstructions|ogCommands"></div>
+ <textarea *ngIf="editInstructions == true" class="og-instructions" [(ngModel)]="ogCommandsService.ogInstructions"></textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.scss b/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.scss
new file mode 100644
index 00000000..08b1082b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.scss
@@ -0,0 +1,3 @@
+app-execute-command {
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.ts
new file mode 100644
index 00000000..9560258a
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/execute-command/execute-command.component.ts
@@ -0,0 +1,142 @@
+import {Component, OnInit} from '@angular/core';
+
+import {ToasterService} from '../../../service/toaster.service';
+import {ActivatedRoute, Router} from '@angular/router';
+import {TranslateService} from '@ngx-translate/core';
+import {OgCommonService} from '../../../service/og-common.service';
+import {OgSweetAlertService} from '../../../service/og-sweet-alert.service';
+import {AuthModule} from 'globunet-angular/core';
+import {User} from '../../../model/user';
+import {OGCommandsService} from '../../../service/og-commands.service';
+import {CommandService} from '../../../api/command.service';
+import {CommandFormType} from '../../../form-type/command.form-type';
+import {Command} from '../../../model/command';
+
+@Component({
+ selector: 'app-execute-command',
+ templateUrl: './execute-command.component.html',
+ styleUrls: [ './execute-command.component.scss' ]
+})
+export class ExecuteCommandComponent implements OnInit {
+ execution = {script: '', clients: ''};
+ selectedCommand = {
+ inputs: [],
+ script: ''
+ };
+ newCommand = 'true';
+ private user: User;
+ private selectedClients = [];
+ private form = [];
+ private formType: CommandFormType;
+ public commands: Command[] = [];
+ editInstructions = false;
+
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(public ogCommandsService: OGCommandsService,
+ private authModule: AuthModule,
+ private router: Router,
+ private activatedRoute: ActivatedRoute,
+ private ogCommonService: OgCommonService,
+ private commandService: CommandService,
+ private ogSweetAlert: OgSweetAlertService,
+ private toaster: ToasterService,
+ private translate: TranslateService) {
+ this.user = this.authModule.getLoggedUser();
+ }
+
+
+
+
+
+
+ ngOnInit(): void {
+ this.selectedClients = this.ogCommonService.selectedClients;
+ if (this.user && this.selectedClients) {
+ this.loadFormOptions();
+ this.loadCommands();
+ } else {
+ // TODO - dar error?
+ this.ogSweetAlert.error(this.translate.instant('opengnsys_error'), this.translate.instant('not_clients_selected'));
+ this.router.navigate(['/app/ous']);
+ }
+ }
+
+ sendCommand() {
+ let result = true;
+
+ if (!this.execution.script) {
+ result = false;
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('command_not_valid')});
+ } else if (!this.execution.clients) {
+ result = false;
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('not_clients_selected')});
+ }
+ // Si no hubo ningun error
+ if (result === true) {
+ this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$');
+ // Resetar las instrucciones del script opengnsys almacenadas.
+ this.ogCommandsService.ogInstructions = '';
+ this.commandService.execute(this.execution).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: 'success', body: 'Successfully saved'});
+ this.router.navigate(['/app/ous']);
+ },
+ function(error) {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ }
+
+ loadFormOptions() {
+ this.formType = new CommandFormType();
+ this.form = this.formType.getForm();
+ }
+
+ loadCommands() {
+ this.commandService.list().subscribe(
+ (result) => {
+ this.commands = result;
+ }
+ );
+ }
+
+
+ executeSelectedCommand() {
+ // Ejecuta el contenido de ogInstructions
+ this.ogCommandsService.execute('RUN_SCRIPT');
+ }
+
+ updateSelectedCommand() {
+ this.getParamsNumber(this.selectedCommand);
+ this.ogCommandsService.ogInstructions = this.selectedCommand.script;
+ }
+
+
+ updateScript(i, value) {
+ this.selectedCommand.inputs[i] = value.target.value;
+ let script = this.selectedCommand.script;
+ for (let index = 0; index < this.selectedCommand.inputs.length; index++) {
+ script = script.replace('@' + (index + 1), this.selectedCommand.inputs[index]);
+ }
+ this.ogCommandsService.ogInstructions = script;
+
+ }
+
+ getParamsNumber(command) {
+ const params = [];
+ if (command.parameters === true) {
+ const allparams = command.script.match(/@[1-9]+/g)||[];
+ for (let index = 0; index < allparams.length; index++) {
+ if (params.indexOf(allparams[index]) === -1) {
+ params.push(allparams[index]);
+ }
+ }
+ this.selectedCommand.inputs = params;
+ }
+ return params.length;
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.html b/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.html
new file mode 100644
index 00000000..e8bcdbc5
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.html
@@ -0,0 +1,81 @@
+<section class="content-header">
+ <h1 translate="login_command">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'/app/dashboard'"><i class="fa fa-dashboard"></i>{{'dashboard'|translate}}</a></li>
+ <li><a [routerLink]="'/app/ous'"><i class="fa fa-th"></i>{{'ous'|translate}}</a></li>
+ <li class="active" translate="login_command"></li>
+ </ol>
+</section>
+<section fixed-toolboxbar class="toolboxbar">
+ <div>
+ <div class="col-md-12">
+ <div class="box-tools pull-right">
+ <button class="btn btn-primary" translate="execute" (click)="sendCommand()"></button>
+ </div>
+ </div>
+ </div>
+</section>
+<section style="padding: 0 30px;">
+ <h3 translate="selected_clients"></h3>
+ <app-og-selected-clients></app-og-selected-clients>
+</section>
+<!-- Main content -->
+<section class="content">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box box-primary">
+ <div class="box-header with-border">
+ </div>
+ <div class="box-body">
+ <form role="form" name="vm.Form">
+ <div *ngFor="let client of selectedClients">
+ <table class="table" *ngIf="client && client.id" >
+ <thead>
+ <tr>
+ <th colspan="5">
+ {{client.name}}
+ </th>
+ </tr>
+ <tr>
+ <th translate="select">
+ </th>
+ <th translate="disk">
+ </th>
+ <th translate="partition">
+ </th>
+ <th translate="filesystem">
+ </th>
+ <th translate="osname">
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <ng-container *ngFor="let partition of client.partitions">
+ <tr *ngIf="canLogin(partition)">
+ <td>
+ <input icheck type="radio" name="partition" checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" class="selection-checkbox" [(ngModel)]="selectedPartition" [value]="partition" />
+ </td>
+ <td>
+ {{partition.numDisk}}
+ </td>
+ <td>
+ {{partition.numPartition}}
+ </td>
+ <td>
+ {{partition.filesystem}}
+ </td>
+ <td>
+ {{partition.osName}}
+ </td>
+ </tr>
+ </ng-container>
+ </tbody>
+ </table>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.scss b/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.scss
new file mode 100644
index 00000000..ccb34440
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.scss
@@ -0,0 +1,3 @@
+command {
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.ts
new file mode 100644
index 00000000..af234984
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/command/login-command/login-command.component.ts
@@ -0,0 +1,80 @@
+import {Component, OnInit} from '@angular/core';
+
+import {ToasterService} from '../../../service/toaster.service';
+import {ActivatedRoute, Router} from '@angular/router';
+import {TranslateService} from '@ngx-translate/core';
+import {OgCommonService} from '../../../service/og-common.service';
+import {OgSweetAlertService} from '../../../service/og-sweet-alert.service';
+import {AuthModule} from 'globunet-angular/core';
+import {User} from '../../../model/user';
+import {ImageService} from '../../../api/image.service';
+import {OGCommandsService} from '../../../service/og-commands.service';
+import {Client} from '../../../model/client';
+import {CommandService} from '../../../api/command.service';
+
+@Component({
+ selector: 'app-login-command',
+ templateUrl: './login-command.component.html',
+ styleUrls: [ './login-command.component.scss' ]
+})
+export class LoginCommandComponent implements OnInit {
+ execution = {clients: '', script: '', type: ''};
+ command = {};
+ user: User;
+ selectedClients: Client[];
+ selectedPartition: any;
+ client: Client;
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(public ogCommandsService: OGCommandsService,
+ private authModule: AuthModule,
+ private router: Router,
+ private activatedRoute: ActivatedRoute,
+ private ogCommonService: OgCommonService,
+ private commandService: CommandService,
+ private ogSweetAlert: OgSweetAlertService,
+ private toaster: ToasterService,
+ private translate: TranslateService) {
+ this.user = this.authModule.getLoggedUser();
+ }
+
+
+
+ ngOnInit() {
+ this.selectedClients = this.ogCommonService.selectedClients;
+ if (this.user && this.selectedClients) {
+ this.execution.clients = Object.keys(this.selectedClients).join(',');
+ }
+ }
+
+
+ sendCommand() {
+ if (!this.selectedPartition) {
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('you_must_select_partition')});
+ } else {
+ const disk = this.selectedPartition.numDisk;
+ const partition = this.selectedPartition.numPartition;
+
+ this.execution.script = 'bootOs ' + disk + ' ' + partition + ' &';
+ this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$');
+ this.execution.type = 'RUN_SCRIPT';
+
+ this.commandService.execute(this.execution).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_executed')});
+ this.router.navigate(['app.ous']);
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ }
+
+
+ canLogin(partition) {
+ return partition.osName !== '' && partition.osName !== 'DATA';
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-commands-options/og-commands-options.component.html b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-commands-options/og-commands-options.component.html
index 7f114997..c008d3a1 100644
--- a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-commands-options/og-commands-options.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-commands-options/og-commands-options.component.html
@@ -6,14 +6,14 @@
<li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)"(click)="ogCommandsService.execute('POWER_OFF')" translate="power_off"></a></li>
<li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)"(click)="ogCommandsService.execute('POWER_ON')" translate="power_on"></a></li>
<li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)"(click)="ogCommandsService.execute('REBOOT')" translate="reboot"></a></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'app/commands/login'" translate="login_command"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'/app/commands/login'" translate="login_command"></a></li>
<li role="presentation" class="divider"></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'app/commands/execute'" translate="execute_command"></a></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() != 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'app/commands/create_image'" translate="create_image"></a></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)" [routerLink]="'app/commands/deploy_image'" translate="deploy_image"></a></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)" [routerLink]="'app/commands/delete_cache_image'" translate="delete_cache_image"></a></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'app/commands/partition_format'" translate="partition_format"></a></li>
- <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'app/commands/format'" translate="format"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'/app/commands/execute'" translate="execute_command"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() != 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'/app/commands/create_image'" translate="create_image"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)" [routerLink]="'/app/commands/deploy_image'" translate="deploy_image"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)" [routerLink]="'/app/commands/delete_cache_image'" translate="delete_cache_image"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'/app/commands/partition_format'" translate="partition_format"></a></li>
+ <li role="presentation" class="{{ogCommonService.getSelectionSize() < 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" [routerLink]="'/app/commands/format'" translate="format"></a></li>
<li role="presentation" class="divider"></li>
<li role="presentation" class="{{ogCommonService.getSelectionSize() != 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)"(click)="ogCommandsService.execute('SOFTWARE_INVENTORY')" translate="software_inventary"></a></li>
<li role="presentation" class="{{ogCommonService.getSelectionSize() != 1?'disable-links':''}}"><a role="menuitem" tabindex="-1" href="javascript:void(0)"(click)="ogCommandsService.execute('HARDWARE_INVENTORY')" translate="hardware_inventary"></a></li>
diff --git a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.html b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.html
index efaabd65..2bc015f9 100644
--- a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.html
@@ -1,3 +1,8 @@
-<p>
- og-execute-command-options works!
-</p>
+<div class="btn-group">
+ <button class="btn btn-default"(click)="ogCommandsService.execute('RUN_SCRIPT',{script: ogCommandsService.ogInstructions})">
+ <span translate="execute"></span>
+ </button>
+ <button class="btn btn-primary"(click)="ogCommandsService.execute('RUN_SCRIPT',{script: ogCommandsService.ogInstructions, save: true})">
+ <span translate="save"></span>
+ </button>
+</div>
diff --git a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.ts b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.ts
index 55da5e36..86ccbf53 100644
--- a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-execute-command-options/og-execute-command-options.component.ts
@@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
+import {OGCommandsService} from '../../../../service/og-commands.service';
@Component({
selector: 'app-og-execute-command-options',
@@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core';
})
export class OgExecuteCommandOptionsComponent implements OnInit {
- constructor() { }
+ constructor(public ogCommandsService: OGCommandsService) { }
ngOnInit() {
}
diff --git a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.html b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.html
index e87b931a..ebb52d60 100644
--- a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.html
@@ -1,3 +1,21 @@
-<p>
- og-selected-clients works!
-</p>
+<div class="row">
+ <div *ngFor="let client of selectedClients" class="col-md-2 col-xs-6 padding-5">
+ <div class="info-box client" *ngIf="client && client.id">
+ <span style="position: absolute;">
+ <input icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox"
+ class="selection-checkbox" [(ngModel)]="client.selected"
+ (change)="ogCommonService.selectClient(client, client.parent)"/>
+ </span>
+ <span class="info-box-icon">
+ <i class="fa fa-desktop">
+ </i>
+ </span>
+ <div class="info-box-content">
+ <span class="info-box-text">{{client.name}}</span>
+ <span class="info-box-text">{{client.ip}}</span>
+ <span class="info-box-text">{{client.mac}}</span>
+ </div>
+ <!-- /.info-box-content -->
+ </div>
+ </div>
+</div>
diff --git a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.ts b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.ts
index 9c6f1c4e..a6c7a606 100644
--- a/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/common/og-options/og-selected-clients/og-selected-clients.component.ts
@@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
+import {OgCommonService} from '../../../../service/og-common.service';
+import {Client} from '../../../../model/client';
@Component({
selector: 'app-og-selected-clients',
@@ -6,10 +8,17 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./og-selected-clients.component.css']
})
export class OgSelectedClientsComponent implements OnInit {
+ public selectedClients: Client[];
- constructor() { }
+ constructor(public ogCommonService: OgCommonService) {
+ this.selectedClients = [];
+ }
ngOnInit() {
+ this.selectedClients = this.ogCommonService.selectedClients;
}
+ getClientInfo(c: Client) {
+ console.log(c);
+ }
}
diff --git a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/profiles-group.component.html b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component.html
index 365ceebe..d7a73e89 100644
--- a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/profiles-group.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component.html
@@ -1,47 +1,47 @@
-<mk-box boxColor="warning" headerBorder="true" isCollapsable="true" [isRemovable]="false">
- <mk-box-header class="box-header with-border">
- <i class="fa fa-folder-open-o"></i>
- <h3 class="box-title">
- <div class="btn-group" *ngIf="!content.editing">
- <div mk-dropdown class="btn-group" [isWrapper]="false" >
- <mk-dropdown-toggle>
- <button #toggleElement type="button" class="btn btn-default dropdown-toggle">
- {{content.name}}
- <span class="fa fa-caret-down"></span>
- </button>
- </mk-dropdown-toggle>
- <mk-dropdown-menu>
- <li >
- <a role="menuitem" tabindex="-1" href="#" translate="add_group"></a>
- </li>
- <li >
- <a role="menuitem" tabindex="-1" href="#" translate="add_profile" [routerLink]="'/app/hardware/profile/create/' + content.id "></a>
- </li>
- <li class="divider"></li>
- <li>
- <a class="" href="javascript:void(0)" translate="edit" (click)="content.$$tmpName = content.name; content.editing = true"></a>
- </li>
- <li role="presentation" class="divider"></li>
- <li role="presentation" class="delete-option">
- <a class="" href="javascript:void(0)" translate="delete" (click)="deleteGroup(content.id)"></a>
- </li>
- </mk-dropdown-menu>
- </div>
- </div>
- <div *ngIf="content.editing" class="col-xs-6">
- <input type="text" class="form-control" [(ngModel)]="content.$$tmpName">
- <span class="input-group-btn">
- <button type="button" class="btn btn-default btn-flat" translate="done" (click)="changeGroupName(content)"></button>
- <button type="button" class="btn btn-info btn-flat" translate="cancel" (click)="content.editing = false"></button>
- </span>
- </div>
- </h3>
- <!-- /.box-tools -->
- </mk-box-header>
- <!-- /.box-header -->
- <mk-box-content class="box-body folders" style="display: block;">
- <app-profiles-group *ngFor="let content of content.groups" [content]="content">
- </app-profiles-group>
- <app-profiles-table *ngIf="content.profiles" [profiles]="content.profiles"></app-profiles-table>
- </mk-box-content>
-</mk-box>
+<mk-box boxColor="warning" headerBorder="true" isCollapsable="true" [isRemovable]="false">
+ <mk-box-header class="box-header with-border">
+ <i class="fa fa-folder-open-o"></i>
+ <h3 class="box-title">
+ <div class="btn-group" *ngIf="!content.editing">
+ <div mk-dropdown class="btn-group" [isWrapper]="false" >
+ <mk-dropdown-toggle>
+ <button #toggleElement type="button" class="btn btn-default dropdown-toggle">
+ {{content.name}}
+ <span class="fa fa-caret-down"></span>
+ </button>
+ </mk-dropdown-toggle>
+ <mk-dropdown-menu>
+ <li >
+ <a role="menuitem" tabindex="-1" href="#" translate="add_group"></a>
+ </li>
+ <li >
+ <a role="menuitem" tabindex="-1" href="#" translate="add_profile" [routerLink]="'/app/hardware/profile/create/' + content.id "></a>
+ </li>
+ <li class="divider"></li>
+ <li>
+ <a class="" href="javascript:void(0)" translate="edit" (click)="content.$$tmpName = content.name; content.editing = true"></a>
+ </li>
+ <li role="presentation" class="divider"></li>
+ <li role="presentation" class="delete-option">
+ <a class="" href="javascript:void(0)" translate="delete" (click)="deleteGroup(content.id)"></a>
+ </li>
+ </mk-dropdown-menu>
+ </div>
+ </div>
+ <div *ngIf="content.editing" class="col-xs-6">
+ <input type="text" class="form-control" [(ngModel)]="content.$$tmpName">
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default btn-flat" translate="done" (click)="changeGroupName(content)"></button>
+ <button type="button" class="btn btn-info btn-flat" translate="cancel" (click)="content.editing = false"></button>
+ </span>
+ </div>
+ </h3>
+ <!-- /.box-tools -->
+ </mk-box-header>
+ <!-- /.box-header -->
+ <mk-box-content class="box-body folders" style="display: block;">
+ <app-profiles-group *ngFor="let content of content.groups" [content]="content">
+ </app-profiles-group>
+ <app-profiles-table *ngIf="content.profiles" [profiles]="content.profiles"></app-profiles-table>
+ </mk-box-content>
+</mk-box>
diff --git a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/profiles-group.component.ts b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component.ts
index f9dbd868..884bb680 100644
--- a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/profiles-group.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-group/hardware-profiles-group.component.ts
@@ -1,14 +1,14 @@
-import {ComponentMetadata} from 'codelyzer/angular/metadata';
-import {Component, Input} from '@angular/core';
-
-@Component({
- selector: 'app-profiles-group',
- templateUrl: 'profiles-group.component.html'
-})
-export class ProfilesGroupComponent {
- @Input() content;
-
- constructor() {
- console.log(this.content);
- }
-}
+import {ComponentMetadata} from 'codelyzer/angular/metadata';
+import {Component, Input} from '@angular/core';
+
+@Component({
+ selector: 'app-profiles-group',
+ templateUrl: 'hardware-profiles-group.component.html'
+})
+export class HardwareProfilesGroupComponent {
+ @Input() content;
+
+ constructor() {
+ console.log(this.content);
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/profiles-table.component.html b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component.html
index 45f17240..70bd2fd1 100644
--- a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/profiles-table.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component.html
@@ -1,61 +1,61 @@
-<table class="table table-hover">
- <tbody>
- <tr>
- <th translate="description"></th>
- <th translate="windowsboot"></th>
- <th translate="options"></th>
- </tr>
- <tr *ngFor="let profile of profiles; let index = index" class="{{(index%2 == 0)?'odd':'even'}}">
- <td>
- <span *ngIf="profile.$$editing">
- <input type="text" class="form-control" [(ngModel)]="profile.$$tmpDescription">
- </span>
- <span *ngIf="!profile.$$editing">
- {{profile.description}}
- </span>
- </td>
- <td>
- <span *ngIf="profile.$$editing">
- <select class="form-control"[(ngModel)]="profile.$$tmpWindowsboot">
- <option [value]="item" *ngFor="let item of windowsboots"> {{item}}</option>
- </select>
- </span>
- <span *ngIf="!profile.$$editing">
- {{profile.windowsboot}}
- </span>
- </td>
- <td class="right">
- <ng-container *ngIf="profile.$$editing">
- <div class="btn-group ">
- <button class="btn btn-primary " translate="ok" (click)="saveHardwareProfile(profile)"></button>
- <button class="btn btn-default " translate="cancel" (click)="profile.$$editing = false"></button>
- </div>
- </ng-container>
- <ng-container *ngIf="!profile.$$editing">
- <app-table-action [rowData]="profile" [options]="tableOptions" (edit)="editHardwareProfile($event)" (delete)="deleteHardwareProfile($event)"></app-table-action>
-<!--
- <div class="btn-group visible-md visible-lg hidden-sm hidden-xs">
- <button class="btn btn-default" translate="edit" (click)="editHardwareProfile(profile)"></button>
- <button class="btn btn-default" href="javascript:void(0)" translate="config" (click)="goToEditProfile(profile)"></button>
- <button class="btn btn-danger " translate="delete" (click)="deleteHardwareProfile(profile)"></button>
- </div>
- <div class="btn-group hidden-md hidden-lg">
- <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
- <i class="fa fa-gear"></i>
- <span class="caret"></span>
- <span class="sr-only">Toggle Dropdown</span>
- </button>
- <ul class="dropdown-menu" role="menu">
- <li class="btn-group-vertical">
- <button class="btn btn-default" translate="edit" (click)="editHardwareProfile(profile)"></button>
- <button class="btn btn-default" href="javascript:void(0)" translate="config" ui-sref="goToEditProfile(profile)"></button>
- <button class="btn btn-danger" href="javascript:void(0)" translate="delete" (click)="deleteHardwareProfile(profile)"></button>
- </li>
- </ul>
- </div>
--->
- </ng-container>
- </td>
- </tr>
- </tbody>
- </table>
+<table class="table table-hover">
+ <tbody>
+ <tr>
+ <th translate="description"></th>
+ <th translate="windowsboot"></th>
+ <th translate="options"></th>
+ </tr>
+ <tr *ngFor="let profile of profiles; let index = index" class="{{(index%2 == 0)?'odd':'even'}}">
+ <td>
+ <span *ngIf="profile.$$editing">
+ <input type="text" class="form-control" [(ngModel)]="profile.$$tmpDescription">
+ </span>
+ <span *ngIf="!profile.$$editing">
+ {{profile.description}}
+ </span>
+ </td>
+ <td>
+ <span *ngIf="profile.$$editing">
+ <select class="form-control"[(ngModel)]="profile.$$tmpWindowsboot">
+ <option [value]="item" *ngFor="let item of windowsboots"> {{item}}</option>
+ </select>
+ </span>
+ <span *ngIf="!profile.$$editing">
+ {{profile.windowsboot}}
+ </span>
+ </td>
+ <td class="right">
+ <ng-container *ngIf="profile.$$editing">
+ <div class="btn-group ">
+ <button class="btn btn-primary " translate="ok" (click)="saveHardwareProfile(profile)"></button>
+ <button class="btn btn-default " translate="cancel" (click)="profile.$$editing = false"></button>
+ </div>
+ </ng-container>
+ <ng-container *ngIf="!profile.$$editing">
+ <app-table-action [rowData]="profile" [options]="tableOptions" (edit)="editHardwareProfile($event)" (delete)="deleteHardwareProfile($event)"></app-table-action>
+<!--
+ <div class="btn-group visible-md visible-lg hidden-sm hidden-xs">
+ <button class="btn btn-default" translate="edit" (click)="editHardwareProfile(profile)"></button>
+ <button class="btn btn-default" href="javascript:void(0)" translate="config" (click)="goToEditProfile(profile)"></button>
+ <button class="btn btn-danger " translate="delete" (click)="deleteHardwareProfile(profile)"></button>
+ </div>
+ <div class="btn-group hidden-md hidden-lg">
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+ <i class="fa fa-gear"></i>
+ <span class="caret"></span>
+ <span class="sr-only">Toggle Dropdown</span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li class="btn-group-vertical">
+ <button class="btn btn-default" translate="edit" (click)="editHardwareProfile(profile)"></button>
+ <button class="btn btn-default" href="javascript:void(0)" translate="config" ui-sref="goToEditProfile(profile)"></button>
+ <button class="btn btn-danger" href="javascript:void(0)" translate="delete" (click)="deleteHardwareProfile(profile)"></button>
+ </li>
+ </ul>
+ </div>
+-->
+ </ng-container>
+ </td>
+ </tr>
+ </tbody>
+ </table>
diff --git a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/profiles-table.component.ts b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component.ts
index c1a155ff..76db2008 100644
--- a/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/profiles-table.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/hardware/hardware-profiles/profiles-table/hardware-profiles-table.component.ts
@@ -1,101 +1,101 @@
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
-import {HardwareProfile} from '../../../../model/hardware-profile';
-import {HardwareProfileService} from '../../../../api/hardware-profile.service';
-import {ToasterService} from '../../../../service/toaster.service';
-import {TranslateService} from '@ngx-translate/core';
-import {OgSweetAlertService} from '../../../../service/og-sweet-alert.service';
-import {Router} from '@angular/router';
-import {environment} from '../../../../../environments/environment';
-import {PartitionInfo} from '../../../../model/image';
-import {Ng2TableActionComponent} from '../../../common/table-action/ng2-table-action.component';
-
-@Component({
- selector: 'app-profiles-table',
- templateUrl: 'profiles-table.component.html'
-})
-export class ProfilesTableComponent implements OnInit {
- @Input() profiles;
- windowsboots: any;
- tableOptions: any;
-
- public constructor(private router: Router, private hardwareProfileService: HardwareProfileService, private ogSweetAlert: OgSweetAlertService, private toaster: ToasterService, private translate: TranslateService) {
-
- }
- ngOnInit(): void {
- this.windowsboots = environment.windowsboots;
- this.tableOptions = {
- override: false,
- buttons: [
- {
- action: 'edit'
- },
- {
- label: 'configure',
- handler: (profile) => this.goToEditProfile(profile),
- classes: 'btn-default'
- },
- {
- action: 'delete'
- }
- ]
- };
- }
-
- editHardwareProfile(hardwareProfile) {
- hardwareProfile.$$editing = true;
- hardwareProfile.$$tmpName = hardwareProfile.name;
- hardwareProfile.$$tmpDescription = hardwareProfile.description;
- hardwareProfile.$$tmpWindowsboot = hardwareProfile.windowsboot;
- }
-
- saveHardwareProfile(hardwareProfile) {
- hardwareProfile.$$editing = false;
- hardwareProfile.name = hardwareProfile.$$tmpName;
- hardwareProfile.description = hardwareProfile.$$tmpDescription;
- hardwareProfile.windowsboot = hardwareProfile.$$tmpWindowsboot;
- const hpCopy = Object.assign({}, hardwareProfile);
- // TODO - Llamar al servidor para guardar el cambio
- this.hardwareProfileService.update(hpCopy).subscribe(
- (response) => {
- this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_saved')});
- },
- (error) => {
- this.toaster.pop({type: 'error', title: 'error', body: error});
- }
- );
- }
-
- deleteHardwareProfile(hardwareProfile) {
- const self = this;
-
- this.ogSweetAlert.question(this.translate.instant('sure_to_delete') + '?', this.translate.instant('action_cannot_be_undone'),
- function(result) {
- if (result.value === true) {
- self.hardwareProfileService.delete(hardwareProfile.id).subscribe(
- (response) => {
- self.toaster.pop({type: 'success', title: self.translate.instant('success'), body: self.translate.instant('successfully_deleted')});
- const index = self.profiles.indexOf(hardwareProfile);
- if (index !== -1) {
- self.profiles.splice(index, 1);
- }
- },
- (error) => {
- self.toaster.pop({type: 'error', title: self.translate.instant('error'), body: error});
- }
- );
- }
- }
- );
- }
-
- goToEditProfile(profile: HardwareProfile) {
- this.router.navigate(['/app/hardware/profile', profile.id]).then(
- success => {
- console.log(success);
- },
- error => {
- console.log(error);
- }
- );
- }
-}
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {HardwareProfile} from '../../../../model/hardware-profile';
+import {HardwareProfileService} from '../../../../api/hardware-profile.service';
+import {ToasterService} from '../../../../service/toaster.service';
+import {TranslateService} from '@ngx-translate/core';
+import {OgSweetAlertService} from '../../../../service/og-sweet-alert.service';
+import {Router} from '@angular/router';
+import {environment} from '../../../../../environments/environment';
+import {PartitionInfo} from '../../../../model/image';
+import {Ng2TableActionComponent} from '../../../common/table-action/ng2-table-action.component';
+
+@Component({
+ selector: 'app-profiles-table',
+ templateUrl: 'hardware-profiles-table.component.html'
+})
+export class HardwareProfilesTableComponent implements OnInit {
+ @Input() profiles;
+ windowsboots: any;
+ tableOptions: any;
+
+ public constructor(private router: Router, private hardwareProfileService: HardwareProfileService, private ogSweetAlert: OgSweetAlertService, private toaster: ToasterService, private translate: TranslateService) {
+
+ }
+ ngOnInit(): void {
+ this.windowsboots = environment.windowsboots;
+ this.tableOptions = {
+ override: false,
+ buttons: [
+ {
+ action: 'edit'
+ },
+ {
+ label: 'configure',
+ handler: (profile) => this.goToEditProfile(profile),
+ classes: 'btn-default'
+ },
+ {
+ action: 'delete'
+ }
+ ]
+ };
+ }
+
+ editHardwareProfile(hardwareProfile) {
+ hardwareProfile.$$editing = true;
+ hardwareProfile.$$tmpName = hardwareProfile.name;
+ hardwareProfile.$$tmpDescription = hardwareProfile.description;
+ hardwareProfile.$$tmpWindowsboot = hardwareProfile.windowsboot;
+ }
+
+ saveHardwareProfile(hardwareProfile) {
+ hardwareProfile.$$editing = false;
+ hardwareProfile.name = hardwareProfile.$$tmpName;
+ hardwareProfile.description = hardwareProfile.$$tmpDescription;
+ hardwareProfile.windowsboot = hardwareProfile.$$tmpWindowsboot;
+ const hpCopy = Object.assign({}, hardwareProfile);
+ // TODO - Llamar al servidor para guardar el cambio
+ this.hardwareProfileService.update(hpCopy).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_saved')});
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+
+ deleteHardwareProfile(hardwareProfile) {
+ const self = this;
+
+ this.ogSweetAlert.question(this.translate.instant('sure_to_delete') + '?', this.translate.instant('action_cannot_be_undone'),
+ function(result) {
+ if (result.value === true) {
+ self.hardwareProfileService.delete(hardwareProfile.id).subscribe(
+ (response) => {
+ self.toaster.pop({type: 'success', title: self.translate.instant('success'), body: self.translate.instant('successfully_deleted')});
+ const index = self.profiles.indexOf(hardwareProfile);
+ if (index !== -1) {
+ self.profiles.splice(index, 1);
+ }
+ },
+ (error) => {
+ self.toaster.pop({type: 'error', title: self.translate.instant('error'), body: error});
+ }
+ );
+ }
+ }
+ );
+ }
+
+ goToEditProfile(profile: HardwareProfile) {
+ this.router.navigate(['/app/hardware/profile', profile.id]).then(
+ success => {
+ console.log(success);
+ },
+ error => {
+ console.log(error);
+ }
+ );
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/image/edit/image-edit.component.ts b/admin/WebConsole3/frontend/src/app/pages/image/edit/image-edit.component.ts
index 1117762b..8bc33f44 100644
--- a/admin/WebConsole3/frontend/src/app/pages/image/edit/image-edit.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/image/edit/image-edit.component.ts
@@ -1,76 +1,100 @@
-import {Component, OnInit} from '@angular/core';
-
-import { ImageService } from 'src/app/api/image.service';
-import {Image, PartitionInfo} from 'src/app/model/image';
-
-import {ActivatedRoute, Router} from '@angular/router';
-import {ToasterService} from '../../../service/toaster.service';
-import {TranslateService} from '@ngx-translate/core';
-import {ImageFormType} from '../../../form-type/image.form-type';
-import {RepositoryService} from '../../../api/repository.service';
-
-@Component({
- selector: 'app-image',
- templateUrl: './image-edit.component.html',
- styleUrls: [ './image-edit.component.scss' ]
-})
-export class ImageEditComponent implements OnInit {
- image: Image;
- constants: any;
- private formType = new ImageFormType();
- public form: any;
-
- // this tells the tabs component which Pages
- // should be each tab's root Page
- constructor(private router: Router, private activatedRouter: ActivatedRoute, private imageService: ImageService, private repositoryService: RepositoryService, private translate: TranslateService, private toaster: ToasterService) {
- this.form = this.formType.getForm();
- }
-
- ngOnInit(): void {
- this.image = new Image();
- this.activatedRouter.paramMap.subscribe(
- (data: any) => {
- if (data.params.id) {
- this.imageService.read(data.params.id).subscribe(
- image => {
- this.image = image;
- },
- error => {
- this.toaster.pop({type: 'error', title: 'error', body: error});
- }
- );
- }
- }
- );
- this.repositoryService.list().subscribe(
- data => {
- this.formType.getField(this.form, 'repository').options = {
- items: data,
- label: 'name',
- value: 'id'
- }
- }
- )
- }
-
- getImageFileSystem(image) {
- const result = '';
- if (typeof image.partitionInfo === 'string') {
- image.partitionInfo = JSON.parse(image.partitionInfo);
- } else if (!image.partitionInfo) {
- image.partitionInfo = {};
- }
- return image.partitionInfo.filesystem;
- }
-
-
- getPartitionType(partition) {
- // buscar la particion en el array global
- let result = this.constants.partitionTypes.filter(function (obj) {
- return obj.id === partition.id;
- });
- result = result[0];
- return result.type;
- }
-
-}
+import {Component, OnInit} from '@angular/core';
+
+import { ImageService } from 'src/app/api/image.service';
+import {Image, PartitionInfo} from 'src/app/model/image';
+
+import {ActivatedRoute, Router} from '@angular/router';
+import {ToasterService} from '../../../service/toaster.service';
+import {TranslateService} from '@ngx-translate/core';
+import {ImageFormType} from '../../../form-type/image.form-type';
+import {RepositoryService} from '../../../api/repository.service';
+import {Observable} from 'rxjs';
+
+@Component({
+ selector: 'app-image',
+ templateUrl: './image-edit.component.html',
+ styleUrls: [ './image-edit.component.scss' ]
+})
+export class ImageEditComponent implements OnInit {
+ image: Image;
+ constants: any;
+ private formType = new ImageFormType();
+ public form: any;
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(private router: Router, private activatedRouter: ActivatedRoute, private imageService: ImageService, private repositoryService: RepositoryService, private translate: TranslateService, private toaster: ToasterService) {
+ this.form = this.formType.getForm();
+ }
+
+ ngOnInit(): void {
+ this.image = new Image();
+ this.activatedRouter.paramMap.subscribe(
+ (data: any) => {
+ if (data.params.id) {
+ this.imageService.read(data.params.id).subscribe(
+ image => {
+ this.image = image;
+ if (typeof this.image.partitionInfo === 'string') {
+ this.image.partitionInfo = JSON.parse(this.image.partitionInfo);
+ } else if (!this.image.partitionInfo) {
+ this.image.partitionInfo = new PartitionInfo();
+ }
+ },
+ error => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ }
+ );
+ this.repositoryService.list().subscribe(
+ data => {
+ this.formType.getField(this.form, 'repository').options = {
+ items: data,
+ label: 'name',
+ value: 'id'
+ };
+ }
+ );
+ }
+
+ getImageFileSystem(image) {
+ const result = '';
+ if (typeof image.partitionInfo === 'string') {
+ image.partitionInfo = JSON.parse(image.partitionInfo);
+ } else if (!image.partitionInfo) {
+ image.partitionInfo = {};
+ }
+ return image.partitionInfo.filesystem;
+ }
+
+
+ getPartitionType(partition) {
+ // buscar la particion en el array global
+ let result = this.constants.partitionTypes.filter(function (obj) {
+ return obj.id === partition.id;
+ });
+ result = result[0];
+ return result.type;
+ }
+
+ save() {
+ let request: Observable<any>;
+ if (this.image.id !== 0) {
+ request = this.imageService.update(this.image);
+ } else {
+ request = this.imageService.create(this.image);
+ }
+ request.subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: this.translate.instant('success'), body: this.translate.instant('successfully_saved')});
+ this.router.navigate(['/app/images']);
+
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/image/image.component.html b/admin/WebConsole3/frontend/src/app/pages/image/image.component.html
index 09ba6036..a5b700ac 100644
--- a/admin/WebConsole3/frontend/src/app/pages/image/image.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/image/image.component.html
@@ -9,16 +9,16 @@
</section>
<section fixed-toolboxbar class="toolboxbar">
<div class="row">
- <div class="col-10">
+ <div class="col-md-10 col-10">
<div class="input-group">
- <input type="text" name="q" class="form-control" placeholder="{{'search'|translate}}..." ng-model="vm.ngTableSearch.text">
+ <input type="text" name="q" class="form-control" placeholder="{{'search'|translate}}..." >
<span class="input-group-btn">
<button type="button" name="search" id="search-btn" class="btn btn-flat btn-default"><i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
- <div class="col-2" style="margin-top: 5px;margin-bottom: 5px;">
+ <div class="col-md-2 col-2" style="margin-top: 5px;margin-bottom: 5px;">
<div class="box-tools">
<mk-dropdown class="btn-group" [isWrapper]="false" >
<mk-dropdown-toggle>
diff --git a/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.html b/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.html
new file mode 100644
index 00000000..9d96cde9
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.html
@@ -0,0 +1,34 @@
+<section class="content-header">
+ <h1 translate="new_image">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'/app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
+ <li><a [routerLink]="'/app/images'"><i class="fa fa-cubes"></i> {{'images'|translate}}</a></li>
+ <li class="active" translate="edit_image"></li>
+ </ol>
+</section>
+<section fixed-toolboxbar class="toolboxbar">
+ <div>
+ <div class="col-md-12">
+ <div class="box-tools pull-right">
+ <button class="btn btn-primary" translate="save" (click)="save()"></button>
+ </div>
+ </div>
+ </div>
+</section>
+<!-- Main content -->
+<section class="content">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="box box-primary">
+ <div class="box-header with-border">
+ </div>
+ <div class="box-body">
+ <form role="form" gbn-auto-form name="Form" ng-submit="saveImage(Form)" form-options="formOptions" form-model="image">
+ <app-form-input [model]="menu" [cols]="1" [formType]="form"></app-form-input>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
diff --git a/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.scss b/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.scss
new file mode 100644
index 00000000..1382f194
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.scss
@@ -0,0 +1,3 @@
+image {
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.ts b/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.ts
new file mode 100644
index 00000000..d52f53ad
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/menu/edit/menu-edit.component.ts
@@ -0,0 +1,77 @@
+import {Component, OnInit} from '@angular/core';
+
+
+import {ActivatedRoute, Router} from '@angular/router';
+import {ToasterService} from '../../../service/toaster.service';
+import {TranslateService} from '@ngx-translate/core';
+import {MenuFormType} from '../../../form-type/menu.form-type';
+import {RepositoryService} from '../../../api/repository.service';
+import {Observable} from 'rxjs';
+import {MenuService} from '../../../api/menu.service';
+import {Menu} from '../../../model/menu';
+import {OgCommonService} from '../../../service/og-common.service';
+
+@Component({
+ selector: 'app-menu',
+ templateUrl: './menu-edit.component.html',
+ styleUrls: [ './menu-edit.component.scss' ]
+})
+export class MenuEditComponent implements OnInit {
+ menu: Menu;
+ constants: any;
+ private formType = new MenuFormType();
+ public form: any;
+
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(private router: Router, private activatedRouter: ActivatedRoute, private ogCommonService: OgCommonService, private menuService: MenuService, private translate: TranslateService, private toaster: ToasterService) {
+ this.form = this.formType.getForm();
+ }
+
+ ngOnInit(): void {
+ this.menu = new Menu();
+ this.ogCommonService.loadEngineConfig().subscribe(
+ data => {
+ this.formType.getField(this.form, 'resolution').options = {
+ items: data.constants.menus.resolutions,
+ label: 'text',
+ value: 'id'
+ };
+ }
+ );
+ this.activatedRouter.paramMap.subscribe(
+ (data: any) => {
+ if (data.params.id) {
+ this.menuService.read(data.params.id).subscribe(
+ menu => {
+ this.menu = menu;
+ },
+ error => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ }
+ );
+ }
+
+
+ save() {
+ let request: Observable<any>;
+ if (this.menu.id !== 0) {
+ request = this.menuService.update(this.menu);
+ } else {
+ request = this.menuService.create(this.menu);
+ }
+ request.subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: this.translate.instant('success'), body: this.translate.instant('successfully_saved')});
+ this.router.navigate(['/app/menus']);
+
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.html b/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.html
index 93bab7ab..bc65667b 100644
--- a/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.html
@@ -1 +1,51 @@
-<div>Html template for class Menu</div> \ No newline at end of file
+<div ui-view>
+ <section class="content-header">
+ <h1 translate="menus">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
+ <li class="active" translate="menus"></li>
+ </ol>
+ </section>
+ <section fixed-toolboxbar class="toolboxbar">
+ <div >
+ <div class="col-md-12">
+ <div class="input-group">
+ <input type="text" name="q" class="form-control" placeholder="{{'search'|translate}}..." ng-model="vm.ngTableSearch.text">
+ <span class="input-group-btn">
+ <button type="button" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
+ </button>
+ </span>
+ </div>
+ </div>
+ <div class="col-md-12" style="margin-top: 5px;margin-bottom: 5px;">
+
+ <div class="box-tools pull-right">
+ <a [routerLink]="'/app/menus/create'" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+ <span translate="new"></span>
+ </a>
+ </div>
+ </div>
+ </div>
+ </section>
+ <!-- Main content -->
+ <section class="content">
+ <div class="row">
+ <div class="col-md-12">
+ <!-- Info boxes -->
+ <div class="box box-primary">
+ <div class="box-header with-border">
+ <h3 class="box-title" translate="image_list"></h3>
+ </div>
+ <div class="box-body">
+ <ng2-smart-table [source]="menus" [settings]="tableSettings"></ng2-smart-table>
+ </div>
+ <div class="box-footer">
+ </div>
+ <!-- /.col -->
+ </div>
+ </div>
+ </div>
+ <!-- /.row -->
+ </section>
+</div>
diff --git a/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.ts b/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.ts
index a5cecb4e..4c47eb73 100644
--- a/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/menu/menu.component.ts
@@ -1,17 +1,104 @@
-import { Component } from '@angular/core';
-
-import { MenuService } from 'src/app/api/menu.service';
-import { Menu } from 'src/app/model/menu';
-
-@Component({
- selector: 'menu',
- templateUrl: './menu.component.html',
- styleUrls: [ './menu.component.scss' ]
-})
-export class MenuComponent {
- // this tells the tabs component which Pages
- // should be each tab's root Page
- constructor(public menuService: MenuService) {
- }
-
-}
+import {Component, OnInit} from '@angular/core';
+
+import { MenuService } from 'src/app/api/menu.service';
+import { Menu } from 'src/app/model/menu';
+import {PartitionInfo} from '../../model/image';
+import {Ng2TableActionComponent} from '../common/table-action/ng2-table-action.component';
+import {TranslateService} from '@ngx-translate/core';
+import {Router} from '@angular/router';
+import {OgSweetAlertService} from '../../service/og-sweet-alert.service';
+
+@Component({
+ selector: 'app-menu',
+ templateUrl: './menu.component.html',
+ styleUrls: [ './menu.component.scss' ]
+})
+export class MenuComponent implements OnInit {
+ public menus: Menu[];
+ private tableSettings: any;
+ // this tells the tabs component which Pages
+ // should be each tab's root Page
+ constructor(public menuService: MenuService, private router: Router, private ogSweetAlert: OgSweetAlertService, private translate: TranslateService) {
+ }
+
+ ngOnInit(): void {
+ this.menuService.list().subscribe(
+ data => {
+ this.menus = data;
+ },
+ error => {
+
+ }
+ );
+ const self = this;
+ this.tableSettings = {
+ columns: {
+ title: {
+ title: this.translate.instant('title')
+ },
+ description: {
+ title: this.translate.instant('description')
+ },
+ comments: {
+ title: this.translate.instant('comments'),
+ },
+ resolution: {
+ title: this.translate.instant('resolution')
+ },
+ options: {
+ title: 'Options',
+ filter: false,
+ sort: false,
+ type: 'custom',
+ renderComponent: Ng2TableActionComponent,
+ onComponentInitFunction(instance) {
+ instance.edit.subscribe(row => {
+ self.router.navigate(['/app/menus/edit/', row.id]);
+ });
+ instance.delete.subscribe(row => {
+ self.deleteMenu(row);
+ });
+ }
+ },
+ },
+ actions: {
+ position: 'right',
+ add: false,
+ edit: false,
+ delete: false
+ }
+ };
+ }
+
+ deleteMenu(menu) {
+ const self = this;
+ this.ogSweetAlert.swal({
+ title: this.translate.instant('sure_to_delete') + '?',
+ message: this.translate.instant('action_cannot_be_undone'),
+ type: 'warning',
+ showCancelButton: true,
+ confirmButtonColor: '#3c8dbc',
+ confirmButtonText: this.translate.instant('yes_delete'),
+ closeOnConfirm: true
+ }).then(
+ function(result) {
+ if (result === true) {
+
+ this.menuService.delete(menu.id).then(
+ function(response) {
+ this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_deleted')});
+ // Buscar el elemento en el array y borrarlo
+ const index = this.images.indexOf(menu);
+ if (index !== -1) {
+ this.images.splice(menu, 1);
+ }
+ },
+ function(error) {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ });
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.html b/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.html
index 86508a31..32b0a4db 100644
--- a/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.html
@@ -24,7 +24,7 @@
</td>
<td class="right">
<div class="btn-group visible-md visible-lg hidden-sm hidden-xs">
- <button class="btn btn-default " translate="edit" [routerLink]="'app/client.edit({ou: content.id, clientId: client.id})'"></button>
+ <button class="btn btn-default " translate="edit" [routerLink]="'/app/clients/edit/'+client.id"></button>
<button class="btn btn-danger " translate="delete" (click)="deleteClient(client)"></button>
</div>
<div class="btn-group hidden-md hidden-lg">
@@ -35,7 +35,7 @@
</button>
<ul class="dropdown-menu" role="menu">
<li class="btn-group-vertical">
- <button class="btn btn-default" href="javascript:void(0)" translate="edit" [routerLink]="'app/client.edit({ou: content.id, clientId: client.id})'"></button>
+ <button class="btn btn-default" href="javascript:void(0)" translate="edit" [routerLink]="'/app/clients/edit/'+client.id"></button>
<button class="btn btn-danger" href="javascript:void(0)" translate="delete" (click)="deleteClient(client)"></button>
</li>
</ul>
diff --git a/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.ts b/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.ts
index b65b2ffa..743ba965 100644
--- a/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/organizational-unit/ou-clients/ou-client.component.ts
@@ -41,6 +41,7 @@ export class OuClientComponent {
}
deleteClient(client) {
+ const self = this;
this.ogSweetAlert.swal(
{
title: this.translate.instant('sure_to_delete') + '?',
@@ -52,18 +53,18 @@ export class OuClientComponent {
}).then(
function(response) {
- if (response === true) {
- this.clientService.delete(client.id).then(
- function(success) {
+ if (response.value === true) {
+ self.clientService.delete(client.id).subscribe(
+ (success) => {
// Lo borramos de la unidad organizativa
- const index = this.ou.clients.indexOf(client);
+ const index = self.ou.clients.indexOf(client);
if (index !== -1) {
- this.ou.clients.splice(index, 1);
+ self.ou.clients.splice(index, 1);
}
- this.toaster.pop({type: 'success', title: 'success', body: 'Successfully deleted'});
+ self.toaster.pop({type: 'success', title: 'success', body: 'Successfully deleted'});
},
- function(error) {
- this.toaster.pop({type: 'error', title: 'error', body: error});
+ (error) => {
+ self.toaster.pop({type: 'error', title: 'error', body: error});
}
);
}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.html
new file mode 100644
index 00000000..65c3cacb
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.html
@@ -0,0 +1,45 @@
+<mk-box [boxColor]="'warning'" [isRemovable]="false">
+ <mk-box-header class="box-header with-border">
+ <i class="fa fa-folder-open-o"></i>
+ <h3 class="box-title">
+ <div mk-dropdown class="btn-group" *ngIf="!content.$$editing">
+ <mk-dropdown-toggle>
+ <button #toggleElement type="button" class="btn btn-default dropdown-toggle" >
+ {{content.name}}
+ <span class="fa fa-caret-down"></span>
+ </button>
+ </mk-dropdown-toggle>
+ <mk-dropdown-menu>
+ <li role="presentation">
+ <a role="menuitem" tabindex="-1" href="#" translate="add_group"></a>
+ </li>
+ <li role="presentation">
+ <a role="menuitem" tabindex="-1" href="#" translate="add_software_component"></a>
+ </li>
+ <li role="presentation" class="divider"></li>
+ <li>
+ <a class="" href="javascript:void(0)" translate="edit" (click)="content.$$tmpDescription = content.description; content.$$editing = true"></a>
+ </li>
+ <li role="presentation" class="divider"></li>
+ <li role="presentation" class="delete-option">
+ <a class="" href="javascript:void(0)" translate="delete" (click)="vm.deleteGroup(content.id)"></a>
+ </li>
+ </mk-dropdown-menu>
+ </div>
+ <div *ngIf="content.$$editing" class="col-xs-6">
+ <input type="text" class="form-control" [(ngModel)]="content.$$tmpDescription">
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default btn-flat" translate="done" (click)="changeGroupName(content)"></button>
+ <button type="button" class="btn btn-info btn-flat" translate="cancel" (click)="content.$$editing = false"></button>
+ </span>
+ </div>
+ </h3>
+ <!-- /.box-tools -->
+ </mk-box-header>
+ <!-- /.box-header -->
+ <mk-box-content class="box-body folders" style="display: block;">
+ <app-software-component-group *ngFor="let content of content.groups" [content]="content" [softwareTypes]="softwareTypes">
+ </app-software-component-group>
+ <app-software-components-table *ngIf="content.components" [components]="content.components" [softwareTypes]="softwareTypes"></app-software-components-table>
+ </mk-box-content>
+</mk-box>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.ts
new file mode 100644
index 00000000..d27504a4
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-group/software-components-group.component.ts
@@ -0,0 +1,10 @@
+import {Component, Input} from '@angular/core';
+
+@Component({
+ selector: 'app-software-component-group',
+ templateUrl: 'software-components-group.component.html'
+})
+export class SoftwareComponentsGroupComponent {
+ @Input() content;
+ @Input() softwareTypes;
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.html
new file mode 100644
index 00000000..fb4bdbd2
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.html
@@ -0,0 +1,43 @@
+<table class="table table-hover">
+ <tbody>
+ <tr>
+ <th translate="description"></th>
+ <th translate="type"></th>
+ <!--th translate="imageUrl"></th-->
+ <th translate="options"></th>
+ </tr>
+ <tr *ngFor="let softwareComponent of components; let index = index" class="{{(index%2 == 0)?'odd':'even'}}">
+ <td>
+ <span *ngIf="softwareComponent.$$editing">
+ <input type="text" class="form-control" [(ngModel)]="softwareComponent.$$tmpDescription">
+ </span>
+ <span *ngIf="!softwareComponent.$$editing">
+ {{softwareComponent.description}}
+ </span>
+ </td>
+ <td>
+ <span *ngIf="softwareComponent.$$editing">
+ <select class="form-control" [(ngModel)]="softwareComponent.$$tmpType">
+ <option [value]="softwareType.nemonic" *ngFor="let softwareType of softwareTypes">{{softwareType.name}}</option>
+ </select>
+ </span>
+ <span *ngIf="!softwareComponent.$$editing">
+ <select disabled="disabled" class="form-control" [(ngModel)]="softwareComponent.type">
+ <option [value]="softwareType.nemonic" *ngFor="let softwareType of softwareTypes">{{softwareType.name}}</option>
+ </select>
+ </span>
+ </td>
+ <td class="right">
+ <span *ngIf="softwareComponent.$$editing">
+ <div class="btn-group ">
+ <button class="btn btn-primary " translate="ok" (click)="saveSoftwareComponent(softwareComponent)"></button>
+ <button class="btn btn-default " translate="cancel" (click)="softwareComponent.$$editing = false"></button>
+ </div>
+ </span>
+ <span *ngIf="!softwareComponent.$$editing">
+ <app-table-action [rowData]="softwareComponent" [options]="tableOptions" (edit)="editSoftwareComponent($event)" (delete)="deleteSoftwareComponent($event)"></app-table-action>
+ </span>
+ </td>
+ </tr>
+ </tbody>
+</table>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.ts
new file mode 100644
index 00000000..30341c92
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components-table/software-components-table.component.ts
@@ -0,0 +1,84 @@
+import {Component, Input, OnInit} from '@angular/core';
+import {ToasterService} from '../../../../service/toaster.service';
+import {TranslateService} from '@ngx-translate/core';
+import {OgSweetAlertService} from '../../../../service/og-sweet-alert.service';
+import {Router} from '@angular/router';
+import {SoftwareComponent} from '../../../../model/software-component';
+import {SoftwareComponentService} from '../../../../api/software-component.service';
+import {environment} from '../../../../../environments/environment';
+
+@Component({
+ selector: 'app-software-components-table',
+ templateUrl: 'software-components-table.component.html'
+})
+export class SoftwareComponentsTableComponent implements OnInit {
+ @Input() components;
+ @Input() softwareTypes;
+ public tableOptions: { buttons: ({ action: string } | { handler: (profile) => any; classes: string; label: string })[]; override: boolean };
+
+ public constructor(private router: Router, private softwareComponentService: SoftwareComponentService, private ogSweetAlert: OgSweetAlertService, private toaster: ToasterService, private translate: TranslateService) {
+ }
+
+ ngOnInit(): void {
+ this.tableOptions = {
+ override: false,
+ buttons: [
+ {
+ action: 'edit'
+ },
+ {
+ action: 'delete'
+ }
+ ]
+ };
+ }
+
+ editSoftwareComponent(softwareComponent) {
+ softwareComponent.$$editing = true;
+ softwareComponent.$$tmpDescription = softwareComponent.description;
+ softwareComponent.$$tmpType = softwareComponent.type;
+ }
+ saveSoftwareComponent(softwareComponent: any) {
+ softwareComponent.$$editing = false;
+ softwareComponent.description = softwareComponent.$$tmpDescription;
+ softwareComponent.type = softwareComponent.$$tmpType;
+ const hcCopy = Object.assign({}, softwareComponent);
+
+ // TODO - Llamar al servidor para guardar el cambio
+ this.softwareComponentService.update(hcCopy).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: this.translate.instant('success'), body: this.translate.instant('successfully_saved')});
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: this.translate.instant('error'), body: error});
+ }
+ );
+ }
+
+ deleteSoftwareComponent(softwareComponent: SoftwareComponent) {
+ this.ogSweetAlert.swal({
+ title: this.translate.instant('sure_to_delete') + '?',
+ text: this.translate.instant('action_cannot_be_undone'),
+ type: 'warning',
+ showCancelButton: true,
+ confirmButtonColor: '#3c8dbc',
+ confirmButtonText: this.translate.instant('yes_delete'),
+ closeOnConfirm: true}).then(
+ function(result) {
+ if (result === true) {
+ this.softwareComponentService.delete(softwareComponent.id).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: this.translate.instant('success'), body: this.translate.instant('successfully_deleted')});
+ const index = this.softwareComponentsGroups[0].components.indexOf(softwareComponent);
+ if (index !== -1) {
+ this.softwareComponentsGroups[0].components.splice(index, 1);
+ }
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: this.translate.instant('error'), body: error});
+ }
+ );
+ }
+ });
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.css b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.css
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.html
new file mode 100644
index 00000000..043210de
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.html
@@ -0,0 +1 @@
+<app-software-component-group *ngFor="let content of softwareComponentsGroups" [content]="content" [softwareTypes]="softwareTypes"></app-software-component-group>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.ts
new file mode 100644
index 00000000..78e80784
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-components/software-components.component.ts
@@ -0,0 +1,17 @@
+import {Component, Input, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-software-components',
+ templateUrl: './software-components.component.html',
+ styleUrls: ['./software-components.component.css']
+})
+export class SoftwareComponentsComponent implements OnInit {
+ @Input() softwareTypes;
+ @Input() softwareComponentsGroups;
+ constructor() { }
+
+ ngOnInit() {
+ console.log(this.softwareComponentsGroups);
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.html
new file mode 100644
index 00000000..95b2879a
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.html
@@ -0,0 +1,47 @@
+<mk-box boxColor="warning" headerBorder="true" isCollapsable="true" [isRemovable]="false">
+ <mk-box-header class="box-header with-border">
+ <i class="fa fa-folder-open-o"></i>
+ <h3 class="box-title">
+ <div class="btn-group" *ngIf="!content.editing">
+ <div mk-dropdown class="btn-group" [isWrapper]="false" >
+ <mk-dropdown-toggle>
+ <button #toggleElement type="button" class="btn btn-default dropdown-toggle">
+ {{content.name}}
+ <span class="fa fa-caret-down"></span>
+ </button>
+ </mk-dropdown-toggle>
+ <mk-dropdown-menu>
+ <li >
+ <a role="menuitem" tabindex="-1" href="#" translate="add_group"></a>
+ </li>
+ <li >
+ <a role="menuitem" tabindex="-1" href="#" translate="add_profile" [routerLink]="'/app/software/profile/create/' + content.id "></a>
+ </li>
+ <li class="divider"></li>
+ <li>
+ <a class="" href="javascript:void(0)" translate="edit" (click)="content.$$tmpName = content.name; content.editing = true"></a>
+ </li>
+ <li role="presentation" class="divider"></li>
+ <li role="presentation" class="delete-option">
+ <a class="" href="javascript:void(0)" translate="delete" (click)="deleteGroup(content.id)"></a>
+ </li>
+ </mk-dropdown-menu>
+ </div>
+ </div>
+ <div *ngIf="content.editing" class="col-xs-6">
+ <input type="text" class="form-control" [(ngModel)]="content.$$tmpName">
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default btn-flat" translate="done" (click)="changeGroupName(content)"></button>
+ <button type="button" class="btn btn-info btn-flat" translate="cancel" (click)="content.editing = false"></button>
+ </span>
+ </div>
+ </h3>
+ <!-- /.box-tools -->
+ </mk-box-header>
+ <!-- /.box-header -->
+ <mk-box-content class="box-body folders" style="display: block;">
+ <app-software-profiles-group *ngFor="let content of content.groups" [content]="content">
+ </app-software-profiles-group>
+ <app-software-profiles-table *ngIf="content.profiles" [profiles]="content.profiles"></app-software-profiles-table>
+ </mk-box-content>
+</mk-box>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.ts
new file mode 100644
index 00000000..e3e65420
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-group/software-profiles-group.component.ts
@@ -0,0 +1,14 @@
+import {ComponentMetadata} from 'codelyzer/angular/metadata';
+import {Component, Input} from '@angular/core';
+
+@Component({
+ selector: 'app-software-profiles-group',
+ templateUrl: 'software-profiles-group.component.html'
+})
+export class SoftwareProfilesGroupComponent {
+ @Input() content;
+
+ constructor() {
+ console.log(this.content);
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.html
new file mode 100644
index 00000000..6f362fa9
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.html
@@ -0,0 +1,61 @@
+<table class="table table-hover">
+ <tbody>
+ <tr>
+ <th translate="description"></th>
+ <th translate="windowsboot"></th>
+ <th translate="options"></th>
+ </tr>
+ <tr *ngFor="let profile of profiles; let index = index" class="{{(index%2 == 0)?'odd':'even'}}">
+ <td>
+ <span *ngIf="profile.$$editing">
+ <input type="text" class="form-control" [(ngModel)]="profile.$$tmpDescription">
+ </span>
+ <span *ngIf="!profile.$$editing">
+ {{profile.description}}
+ </span>
+ </td>
+ <td>
+ <span *ngIf="profile.$$editing">
+ <select class="form-control"[(ngModel)]="profile.$$tmpWindowsboot">
+ <option [value]="item" *ngFor="let item of windowsboots"> {{item}}</option>
+ </select>
+ </span>
+ <span *ngIf="!profile.$$editing">
+ {{profile.windowsboot}}
+ </span>
+ </td>
+ <td class="right">
+ <ng-container *ngIf="profile.$$editing">
+ <div class="btn-group ">
+ <button class="btn btn-primary " translate="ok" (click)="saveSoftwareProfile(profile)"></button>
+ <button class="btn btn-default " translate="cancel" (click)="profile.$$editing = false"></button>
+ </div>
+ </ng-container>
+ <ng-container *ngIf="!profile.$$editing">
+ <app-table-action [rowData]="profile" [options]="tableOptions" (edit)="editSoftwareProfile($event)" (delete)="deleteSoftwareProfile($event)"></app-table-action>
+<!--
+ <div class="btn-group visible-md visible-lg hidden-sm hidden-xs">
+ <button class="btn btn-default" translate="edit" (click)="editSoftwareProfile(profile)"></button>
+ <button class="btn btn-default" href="javascript:void(0)" translate="config" (click)="goToEditProfile(profile)"></button>
+ <button class="btn btn-danger " translate="delete" (click)="deleteSoftwareProfile(profile)"></button>
+ </div>
+ <div class="btn-group hidden-md hidden-lg">
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+ <i class="fa fa-gear"></i>
+ <span class="caret"></span>
+ <span class="sr-only">Toggle Dropdown</span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li class="btn-group-vertical">
+ <button class="btn btn-default" translate="edit" (click)="editSoftwareProfile(profile)"></button>
+ <button class="btn btn-default" href="javascript:void(0)" translate="config" ui-sref="goToEditProfile(profile)"></button>
+ <button class="btn btn-danger" href="javascript:void(0)" translate="delete" (click)="deleteSoftwareProfile(profile)"></button>
+ </li>
+ </ul>
+ </div>
+-->
+ </ng-container>
+ </td>
+ </tr>
+ </tbody>
+ </table>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.ts
new file mode 100644
index 00000000..9ea76af2
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles-table/software-profiles-table.component.ts
@@ -0,0 +1,100 @@
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {SoftwareProfile} from '../../../../model/software-profile';
+import {SoftwareProfileService} from '../../../../api/software-profile.service';
+import {ToasterService} from '../../../../service/toaster.service';
+import {TranslateService} from '@ngx-translate/core';
+import {OgSweetAlertService} from '../../../../service/og-sweet-alert.service';
+import {Router} from '@angular/router';
+import {environment} from '../../../../../environments/environment';
+
+
+@Component({
+ selector: 'app-software-profiles-table',
+ templateUrl: 'software-profiles-table.component.html'
+})
+export class SoftwareProfilesTableComponent implements OnInit {
+ @Input() profiles;
+ windowsboots: any;
+ tableOptions: any;
+
+ public constructor(private router: Router, private softwareProfileService: SoftwareProfileService, private ogSweetAlert: OgSweetAlertService, private toaster: ToasterService, private translate: TranslateService) {
+
+ }
+ ngOnInit(): void {
+ this.windowsboots = environment.windowsboots;
+ this.tableOptions = {
+ override: false,
+ buttons: [
+ {
+ action: 'edit'
+ },
+ {
+ label: 'configure',
+ handler: (profile) => this.goToEditProfile(profile),
+ classes: 'btn-default'
+ },
+ {
+ action: 'delete'
+ }
+ ]
+ };
+ }
+
+ editSoftwareProfile(softwareProfile) {
+ softwareProfile.$$editing = true;
+ softwareProfile.$$tmpName = softwareProfile.name;
+ softwareProfile.$$tmpDescription = softwareProfile.description;
+ softwareProfile.$$tmpWindowsboot = softwareProfile.windowsboot;
+ }
+
+ saveSoftwareProfile(softwareProfile) {
+ softwareProfile.$$editing = false;
+ softwareProfile.name = softwareProfile.$$tmpName;
+ softwareProfile.description = softwareProfile.$$tmpDescription;
+ softwareProfile.windowsboot = softwareProfile.$$tmpWindowsboot;
+ const hpCopy = Object.assign({}, softwareProfile);
+ // TODO - Llamar al servidor para guardar el cambio
+ this.softwareProfileService.update(hpCopy).subscribe(
+ (response) => {
+ this.toaster.pop({type: 'success', title: 'success', body: this.translate.instant('successfully_saved')});
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+
+ deleteSoftwareProfile(softwareProfile) {
+ const self = this;
+
+ this.ogSweetAlert.question(this.translate.instant('sure_to_delete') + '?', this.translate.instant('action_cannot_be_undone'),
+ function(result) {
+ if (result.value === true) {
+ self.softwareProfileService.delete(softwareProfile.id).subscribe(
+ (response) => {
+ self.toaster.pop({type: 'success', title: self.translate.instant('success'), body: self.translate.instant('successfully_deleted')});
+ const index = self.profiles.indexOf(softwareProfile);
+ if (index !== -1) {
+ self.profiles.splice(index, 1);
+ }
+ },
+ (error) => {
+ self.toaster.pop({type: 'error', title: self.translate.instant('error'), body: error});
+ }
+ );
+ }
+ }
+ );
+ }
+
+ goToEditProfile(profile: SoftwareProfile) {
+ this.router.navigate(['/app/software/profile', profile.id]).then(
+ success => {
+ console.log(success);
+ },
+ error => {
+ console.log(error);
+ }
+ );
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.css b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.css
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.html
new file mode 100644
index 00000000..adf2e70b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.html
@@ -0,0 +1,3 @@
+<!-- Nested node template -->
+
+<app-software-profiles-group *ngFor="let content of softwareProfileGroups" [content]="content"></app-software-profiles-group>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.ts
new file mode 100644
index 00000000..d7d3987d
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-profiles/software-profiles.component.ts
@@ -0,0 +1,19 @@
+import {Component, Input, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-software-profiles',
+ templateUrl: './software-profiles.component.html',
+ styleUrls: ['./software-profiles.component.css']
+})
+export class SoftwareProfilesComponent implements OnInit {
+
+ @Input() softwareProfileGroups;
+
+ constructor() {
+ }
+
+ ngOnInit() {
+ console.log(this.softwareProfileGroups);
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.css b/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.css
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.html
new file mode 100644
index 00000000..ceda7046
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.html
@@ -0,0 +1,66 @@
+<div class="box box-warning" >
+ <div class="box-header with-border">
+ <i class="fa fa-folder-open-o"></i>
+ <h3 class="box-title">
+ <div class="btn-group">
+ <div>
+ <a href="javascript:void(0)" data-toggle="dropdown" class="dropdown-toggle" translate="software_types">
+ </a>
+ <ul class="dropdown-menu">
+ <li role="presentation">
+ <a role="menuitem" tabindex="-1" href="#" translate="add_software_type"></a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </h3>
+ <div class="box-tools pull-right">
+ <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
+ </button>
+ </div>
+ <!-- /.box-tools -->
+ </div>
+ <!-- /.box-header -->
+ <div class="box-body folders" style="display: block;">
+ <table class="table table-hover">
+ <tbody><tr>
+ <th translate="name"></th>
+ <th translate="options"></th>
+ </tr>
+ <tr *ngFor="let softwareType of softwareTypes; let index = index;" class="{{( index%2 == 0)?'odd':'even'}}">
+ <td>
+ <span *ngIf="!softwareType.$$editing">{{softwareType.name}}</span>
+ <span *ngIf="softwareType.$$editing"><input type="text" class="form-control" [(ngModel)]="softwareType.$$tmpName" /></span>
+ </td>
+ <td class="right">
+ <span *ngIf="softwareType.$$editing">
+ <div class="btn-group ">
+ <button class="btn btn-primary " translate="ok" (click)="saveSoftwareType(softwareType)"></button>
+ <button class="btn btn-default " translate="cancel" (click)="softwareType.$$editing = false"></button>
+ </div>
+ </span>
+ <span *ngIf="!softwareType.$$editing">
+ <div class="btn-group visible-md visible-lg hidden-sm hidden-xs">
+ <button class="btn btn-default " translate="edit" (click)="editSoftwareType(softwareType)"></button>
+ <button class="btn btn-danger " translate="delete" (click)="deleteClient(client.id)"></button>
+ </div>
+ <div class="btn-group hidden-md hidden-lg">
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+ <i class="fa fa-gear"></i>
+ <span class="caret"></span>
+ <span class="sr-only">Toggle Dropdown</span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li class="btn-group-vertical">
+ <button class="btn btn-default" href="javascript:void(0)" translate="edit" (click)="editSoftwareType(softwareType)"></button>
+ <button class="btn btn-danger" href="javascript:void(0)" translate="delete" (click)="deleteClient(client.id)"></button>
+ </li>
+ </ul>
+ </div>
+ </span>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.ts
new file mode 100644
index 00000000..a5e62b2f
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software-types/software-types.component.ts
@@ -0,0 +1,26 @@
+import {Component, Input, OnInit} from '@angular/core';
+
+@Component({
+ selector: 'app-software-types',
+ templateUrl: './software-types.component.html',
+ styleUrls: ['./software-types.component.css']
+})
+export class SoftwareTypesComponent implements OnInit {
+ @Input() softwareTypes;
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+ editSoftwareType(softwareType) {
+ softwareType.$$editing = true;
+ softwareType.$$tmpName = softwareType.name;
+ }
+ saveSoftwareType(softwareType) {
+ softwareType.$$editing = false;
+ softwareType.name = softwareType.$$tmpName;
+ // TODO - Llamar al servidor para guardar el cambio
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software.component.css b/admin/WebConsole3/frontend/src/app/pages/software/software.component.css
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software.component.css
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software.component.html b/admin/WebConsole3/frontend/src/app/pages/software/software.component.html
index adb7ae48..fadb8848 100644
--- a/admin/WebConsole3/frontend/src/app/pages/software/software.component.html
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software.component.html
@@ -1 +1,65 @@
-<div>Html template for class Software</div> \ No newline at end of file
+<ng-container>
+ <section class="content-header">
+ <h1 translate="software">
+ </h1>
+ <ol class="breadcrumb">
+ <li><a [routerLink]="'/app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
+ <li class="active" translate="software"></li>
+ </ol>
+ </section>
+ <section fixed-toolboxbar class="toolboxbar">
+ <div >
+ <div class="col-md-12">
+ <div class="input-group">
+ <input type="text" name="q" class="form-control" placeholder="{{'search'|translate}}..." ng-model="vm.searchText">
+ <span class="input-group-btn">
+ <button type="button" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
+ </button>
+ </span>
+ </div>
+ </div>
+ <div class="col-md-12" style="margin-top: 5px;margin-bottom: 5px;">
+ <div class="box-tools pull-right">
+ <mk-dropdown class="btn-group">
+ <mk-dropdown-toggle>
+ <span translate="new"></span><span class="caret"></span>
+ </mk-dropdown-toggle>
+ <mk-dropdown-menu>
+ <li role="presentation"><a role="menuitem" tabindex="-1" [routerLink]="'/app/software/profile/create'" translate="profile"></a></li>
+ <li role="presentation"><a role="menuitem" tabindex="-1" [routerLink]="'/app/software/component/create'" translate="component"></a></li>
+ <!--li role="presentation"><a role="menuitem" tabindex="-1" [routerLink]="app/software.type.new" translate="software_type"></a></li-->
+ </mk-dropdown-menu>
+ </mk-dropdown>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section class="content">
+ <div class="row">
+ <span style="padding: 0 10px"></span>
+ <div class="col-md-12">
+ <mk-tabs>
+ <mk-tab>
+ <mk-tab-header><span translate="software_profiles"></span></mk-tab-header>
+ <mk-tab-content>
+ <app-software-profiles [softwareProfileGroups]="softwareProfileGroups"></app-software-profiles>
+ </mk-tab-content>
+ </mk-tab>
+ <mk-tab>
+ <mk-tab-header><span translate="software_components"></span></mk-tab-header>
+ <mk-tab-content>
+ <app-software-components [softwareComponentsGroups]="softwareComponentsGroups" [softwareTypes]="softwareTypes"></app-software-components>
+ </mk-tab-content>
+ </mk-tab>
+ <mk-tab>
+ <mk-tab-header><span translate="software_types"></span></mk-tab-header>
+ <mk-tab-content>
+ <app-software-types [softwareTypes]="softwareTypes" ></app-software-types>
+ </mk-tab-content>
+ </mk-tab>
+ </mk-tabs>
+ <!-- /.tab-content -->
+ </div>
+ </div>
+ </section>
+</ng-container>
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software.component.scss b/admin/WebConsole3/frontend/src/app/pages/software/software.component.scss
deleted file mode 100644
index b936796b..00000000
--- a/admin/WebConsole3/frontend/src/app/pages/software/software.component.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-software {
-
-}
diff --git a/admin/WebConsole3/frontend/src/app/pages/software/software.component.ts b/admin/WebConsole3/frontend/src/app/pages/software/software.component.ts
index ef75722b..a51d9560 100644
--- a/admin/WebConsole3/frontend/src/app/pages/software/software.component.ts
+++ b/admin/WebConsole3/frontend/src/app/pages/software/software.component.ts
@@ -1,17 +1,67 @@
-import { Component } from '@angular/core';
-
-import { SoftwareService } from 'src/app/api/software.service';
-import { Software } from 'src/app/model/software';
-
-@Component({
- selector: 'software',
- templateUrl: './software.component.html',
- styleUrls: [ './software.component.scss' ]
-})
-export class SoftwareComponent {
- // this tells the tabs component which Pages
- // should be each tab's root Page
- constructor(public softwareService: SoftwareService) {
- }
-
-}
+import { Component, OnInit } from '@angular/core';
+import {AuthModule} from 'globunet-angular/core';
+import {SoftwareProfileService} from '../../api/software-profile.service';
+import {OgCommonService} from '../../service/og-common.service';
+import {TranslateService} from '@ngx-translate/core';
+import {SoftwareComponentService} from '../../api/software-component.service';
+import {OgSweetAlertService} from '../../service/og-sweet-alert.service';
+import {ToasterService} from '../../service/toaster.service';
+import {SoftwareTypeService} from '../../api/software-type.service';
+
+@Component({
+ selector: 'app-software',
+ templateUrl: './software.component.html',
+ styleUrls: ['./software.component.css']
+})
+export class SoftwareComponent implements OnInit {
+ public softwareProfileGroups: any[] = [];
+ public softwareComponentsGroups: any[][];
+ public softwareComponents: any[] = [];
+ public softwareTypes: any[] = [];
+
+ constructor(private authModule: AuthModule,
+ private ogSweetAlert: OgSweetAlertService,
+ private toaster: ToasterService,
+ private softwareComponentService: SoftwareComponentService,
+ private softwareTypeService: SoftwareTypeService,
+ private softwareProfileService: SoftwareProfileService,
+ private OGCommonService: OgCommonService,
+ private translate: TranslateService) { }
+
+ ngOnInit() {
+ if (this.authModule.getLoggedUser().id !== 0) {
+ this.softwareProfileService.list().subscribe(
+ (response) => {
+ this.softwareProfileGroups = [
+ this.OGCommonService.createGroups(response, 'profiles')
+ ];
+ this.softwareProfileGroups[0].name = this.translate.instant('software_profiles');
+ },
+ (error) => {
+ alert(error);
+ }
+ );
+ this.softwareTypeService.list().subscribe(
+ data => {
+ this.softwareTypes = data;
+ },
+ (error) => {
+ alert(error);
+ }
+ );
+ this.softwareComponentService.list().subscribe(
+ data => {
+ this.softwareComponents = data;
+ this.softwareComponentsGroups = [
+ this.OGCommonService.createGroups(this.softwareComponents, 'components')
+ ];
+ // @ts-ignore
+ this.softwareComponentsGroups[0].name = this.translate.instant('software_components');
+ },
+ error => {
+ alert(error);
+ }
+ );
+ }
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/serializer/image.serializer.ts b/admin/WebConsole3/frontend/src/app/serializer/image.serializer.ts
index f6004e6a..c2043805 100644
--- a/admin/WebConsole3/frontend/src/app/serializer/image.serializer.ts
+++ b/admin/WebConsole3/frontend/src/app/serializer/image.serializer.ts
@@ -1,5 +1,16 @@
-import { Serializer } from "globunet-angular/core/providers/api/serializer";
-
-export class ImageSerializer extends Serializer {
-
-} \ No newline at end of file
+import { Serializer } from 'globunet-angular/core/providers/api/serializer';
+import {Image} from '../model/image';
+
+export class ImageSerializer extends Serializer {
+
+ toJson(resource: Image): any {
+ const image: any = Object.assign({}, resource);
+ if (image.client && image.client.id) {
+ image.client = image.client.id;
+ }
+ if (image.repository && image.repository.id) {
+ image.repository = image.repository.id;
+ }
+ return super.toJson(image);
+ }
+}
diff --git a/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts b/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts
index 7ea08bb8..14e80e84 100644
--- a/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts
+++ b/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts
@@ -1,236 +1,235 @@
-import {ToasterService} from './toaster.service';
-import {OgSweetAlertService} from './og-sweet-alert.service';
-import {CommandService} from '../api/command.service';
-import {OgCommonService} from './og-common.service';
-import {TranslateService} from '@ngx-translate/core';
-import {Router} from '@angular/router';
-import {Injectable} from '@angular/core';
-import * as _ from 'lodash';
-import {environment} from '../../environments/environment';
-
-@Injectable({
- providedIn: 'root'
-})
-export class OGCommandsService {
- public ogInstructions = '';
- public execution: any;
- private commands = [];
-
- constructor(private router: Router, private ogCommonService: OgCommonService, private toaster: ToasterService, private ogSweetAlert: OgSweetAlertService, private commandService: CommandService, private translate: TranslateService) {
- this.execution = {};
- this.ogCommonService.loadEngineConfig().subscribe(
- (response) => {
- this.commands = response.constants.commandtypes;
- }
- );
- }
-
- sendCommand() {
- let result = true;
- // TODO - Comprobar parametros
- if (!this.execution.script) {
- result = false;
- this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('command_not_valid')});
- } else if (!this.execution.clients) {
- result = false;
- this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('not_clients_selected')});
- }
- // Si no hubo ningun error
- if (result === true) {
- this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$');
- // Resetar las instrucciones del script opengnsys almacenadas.
- this.ogInstructions = '';
- this.commandService.execute(this.execution).subscribe(
- (response: any[]) => {
- // Buscar en la respuesta si hay algún statuscode diferente de 200
- const errors = response.filter(function(value) {
- return (value.statusCode && value.statusCode !== '!200');
- } );
- let errorStr = '';
- let toasterOpts = {type: 'success', title: 'success', body: this.translate.instant('successfully_executed')};
- if (errors.length > 0) {
- for (let e = 0; e < errors.length; e++) {
- errorStr += this.translate.instant('execution_failed_in') + ' ' + errors[e].name + '\n';
- }
-
- toasterOpts = {type: 'error', title: 'error', body: errorStr};
- }
- this.toaster.pop(toasterOpts);
- this.router.navigate(['/app/ous']);
- },
- (error) => {
- this.toaster.pop({type: 'error', title: 'error', body: error});
- }
- );
- }
- }
-
- execute(command, params?) {
-
- this.execution.type = command;
-
- if (command === 'HISTORY_LOG') {
- let clientIp = null;
- // Abrir ventana de log
- if (typeof params === 'undefined' || typeof params.clientIp === 'undefined') {
- const client = this.ogCommonService.selectedClients[Object.keys(this.ogCommonService.selectedClients)[0]];
- if (client) {
- clientIp = client.ip;
- }
- } else {
- clientIp = params.clientIp;
- }
-
- if (clientIp) {
- const url = 'http://' + clientIp + environment.commands.HISTORY_LOG;
- window.open(url, '', 'resizable=yes,toolbar=no,status=no,location=no,menubar=no,scrollbars=yes');
- }
- } else if (command === 'REALTIME_LOG') {
- let clientIp = null;
- // Abrir ventana de log
- if (typeof params === 'undefined' || typeof params.clientIp === 'undefined') {
- const client = this.ogCommonService.selectedClients[Object.keys(this.ogCommonService.selectedClients)[0]];
- if (client) {
- clientIp = client.ip;
- }
- } else {
- clientIp = params.clientIp;
- }
-
- if (clientIp) {
- const url = 'http://' + clientIp + environment.commands.REALTIME_LOG;
- window.open(url, '', 'resizable=yes,toolbar=no,status=no,location=no,menubar=no,scrollbars=yes');
- }
- } else if (command === 'SOFTWARE_INVENTORY') {
- const client = this.ogCommonService.selectedClients[Object.keys(this.ogCommonService.selectedClients)[0]];
- // Preparar el scope para el sweet alert
- const options = {
- scope: {
- partitions: [],
- selectedPart: null
- }
- };
-
- // Comprobar tipo de cada particion para ver si es clonable
- // var parttable = $rootScope.constants.partitiontable[client.partitions[0].partitionCode-1];
- // buscar las particiones que sean clonables
- for (let index = 1; index < client.partitions.length; index++) {
- if (client.partitions[index].osName !== 'DATA' && client.partitions[index].osName !== '') {
- // Crear como nombre para mostrar, el disco y partición del sistema
- const obj = Object.assign({}, client.partitions[index]);
- obj.name = 'disco: ' + obj.numDisk + ', part: ' + obj.numPartition + ', SO: ' + client.partitions[index].osName;
- options.scope.partitions.push(obj);
- }
- }
-
- this.ogSweetAlert.swal({
- title: this.translate.instant('select_partition_to_inventary'),
- // text: $filter("translate")("action_cannot_be_undone"),
- type: 'info',
- input: 'select',
- inputOptions: options.scope.partitions,
- showCancelButton: true,
- confirmButtonColor: '#3c8dbc',
- confirmButtonText: this.translate.instant('done'),
- closeOnConfirm: true
- }).then(
- function(result) {
- if (result.value) {
- // Montar el script con el disco y partición elegida
- this.execution.script = this.commands.SOFTWARE_INVENTORY + ' ' + result.value;
- this.loadClients();
- this.sendCommand();
- }
- },
- null);
- } else {
- if (command === 'REBOOT') {
- this.execution.script = environment.commands.REBOOT;
- } else if (command === 'POWER_OFF') {
- this.execution.script = environment.commands.POWER_OFF;
- } else if (command === 'POWER_ON') {
- this.execution.script = 'wakeonlan';
- } else if (command === 'HARDWARE_INVENTORY') {
- this.execution.script = environment.commands.HARDWARE_INVENTORY;
- } else if (command === 'RUN_SCRIPT') {
- this.execution.script = params ? (params.script || this.ogInstructions) : this.ogInstructions;
- } else if (command === 'REFRESH_INFO') {
- this.execution.script = environment.commands.REFRESH_INFO;
- }
-
- // Comprobar si en los parametros viene la opcion de guardar
- if (typeof params !== 'undefined' && params.save === true) {
- const self = this;
- // Mostrar cuadro de dialogo para guardar procedimiento
- this.ogSweetAlert.swal({
- title: this.translate.instant('new_command_name'),
- type: 'info',
- html:
- '<form style="text-align: left; padding-left: 10px">\
- <div class="form-group">\
- <label for="execute" translate="execute">\
- </label>\
- <div class="checkbox clip-check check-primary checkbox-inline">\
- <input id="execute" icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" />\
- </div>\
- </div>\
- <div class="form-group">\
- <label translate="title"></label>\
- <input type="text" class="form-control" id="command.title" />\
- </div>\
- <div class="form-group">\
- <label for="parameters" translate="parameters"></label>\
- <div class="checkbox clip-check check-primary checkbox-inline">\
- <input id="parameters" icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" />\
- </div>\
- <p class="help-block" translate="help_command_parameters"></p>\
- </div>\
- </form>',
- showCancelButton: true,
- confirmButtonColor: '#3c8dbc',
- confirmButtonText: this.translate.instant('done'),
- closeOnConfirm: true,
- preConfirm: () => {
- return {
- execute: (<HTMLInputElement>document.getElementById('execute')).value,
- command: {
- title: (<HTMLInputElement>document.getElementById('command.title')).value,
- parameters: (<HTMLInputElement>document.getElementById('parameters')).value
- }
- };
- }
- }).then(
- function(response) {
- if (response.value) {
- response.value.command.script = this.execution.script;
- response.value.command.type = this.execution.type;
- self.commandService.create(response.value.command).subscribe(
- (success) => {
- // Si se seleccionó continuar con la ejecución
- if (response.value.execute) {
- self.loadClients();
- self.sendCommand();
- } else {
- self.router.navigate(['app/commands']);
- }
- },
- (error) => {
- self.toaster.pop({type: 'error', title: 'error', body: error});
- }
- );
- }
- });
- } else {
- this.loadClients();
- this.sendCommand();
- }
- }
- }
-
- loadClients() {
- if (this.ogCommonService.selectedClients) {
- this.execution.clients = _.join(Object.keys(this.ogCommonService.selectedClients));
- }
- }
-
-}
+import {ToasterService} from './toaster.service';
+import {OgSweetAlertService} from './og-sweet-alert.service';
+import {CommandService} from '../api/command.service';
+import {OgCommonService} from './og-common.service';
+import {TranslateService} from '@ngx-translate/core';
+import {Router} from '@angular/router';
+import {Injectable} from '@angular/core';
+import * as _ from 'lodash';
+import {environment} from '../../environments/environment';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class OGCommandsService {
+ public ogInstructions = '';
+ public execution: any;
+ private commands = [];
+
+ constructor(private router: Router, private ogCommonService: OgCommonService, private toaster: ToasterService, private ogSweetAlert: OgSweetAlertService, private commandService: CommandService, private translate: TranslateService) {
+ this.execution = {};
+ this.ogCommonService.loadEngineConfig().subscribe(
+ (response) => {
+ this.commands = response.constants.commandtypes;
+ }
+ );
+ }
+
+ sendCommand() {
+ let result = true;
+ // TODO - Comprobar parametros
+ if (!this.execution.script) {
+ result = false;
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('command_not_valid')});
+ } else if (!this.execution.clients) {
+ result = false;
+ this.toaster.pop({type: 'error', title: 'error', body: this.translate.instant('not_clients_selected')});
+ }
+ // Si no hubo ningun error
+ if (result === true) {
+ this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$');
+ // Resetar las instrucciones del script opengnsys almacenadas.
+ this.ogInstructions = '';
+ this.commandService.execute(this.execution).subscribe(
+ (response: any[]) => {
+ // Buscar en la respuesta si hay algún statuscode diferente de 200
+ const errors = response.filter(function(value) {
+ return (value.statusCode && value.statusCode !== '!200');
+ } );
+ let errorStr = '';
+ let toasterOpts = {type: 'success', title: 'success', body: this.translate.instant('successfully_executed')};
+ if (errors.length > 0) {
+ for (let e = 0; e < errors.length; e++) {
+ errorStr += this.translate.instant('execution_failed_in') + ' ' + errors[e].name + '\n';
+ }
+
+ toasterOpts = {type: 'error', title: 'error', body: errorStr};
+ }
+ this.toaster.pop(toasterOpts);
+ this.router.navigate(['/app/ous']);
+ },
+ (error) => {
+ this.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ }
+
+ execute(command, params?) {
+
+ this.execution.type = command;
+
+ if (command === 'HISTORY_LOG') {
+ let clientIp = null;
+ // Abrir ventana de log
+ if (typeof params === 'undefined' || typeof params.clientIp === 'undefined') {
+ const client = this.ogCommonService.selectedClients[Object.keys(this.ogCommonService.selectedClients)[0]];
+ if (client) {
+ clientIp = client.ip;
+ }
+ } else {
+ clientIp = params.clientIp;
+ }
+
+ if (clientIp) {
+ const url = 'http://' + clientIp + environment.commands.HISTORY_LOG;
+ window.open(url, '', 'resizable=yes,toolbar=no,status=no,location=no,menubar=no,scrollbars=yes');
+ }
+ } else if (command === 'REALTIME_LOG') {
+ let clientIp = null;
+ // Abrir ventana de log
+ if (typeof params === 'undefined' || typeof params.clientIp === 'undefined') {
+ const client = this.ogCommonService.selectedClients[Object.keys(this.ogCommonService.selectedClients)[0]];
+ if (client) {
+ clientIp = client.ip;
+ }
+ } else {
+ clientIp = params.clientIp;
+ }
+
+ if (clientIp) {
+ const url = 'http://' + clientIp + environment.commands.REALTIME_LOG;
+ window.open(url, '', 'resizable=yes,toolbar=no,status=no,location=no,menubar=no,scrollbars=yes');
+ }
+ } else if (command === 'SOFTWARE_INVENTORY') {
+ const client = this.ogCommonService.selectedClients[Object.keys(this.ogCommonService.selectedClients)[0]];
+ // Preparar el scope para el sweet alert
+ const options = {
+ scope: {
+ partitions: [],
+ selectedPart: null
+ }
+ };
+
+ // Comprobar tipo de cada particion para ver si es clonable
+ // var parttable = $rootScope.constants.partitiontable[client.partitions[0].partitionCode-1];
+ // buscar las particiones que sean clonables
+ for (let index = 1; index < client.partitions.length; index++) {
+ if (client.partitions[index].osName !== 'DATA' && client.partitions[index].osName !== '') {
+ // Crear como nombre para mostrar, el disco y partición del sistema
+ const obj = Object.assign({}, client.partitions[index]);
+ obj.name = 'disco: ' + obj.numDisk + ', part: ' + obj.numPartition + ', SO: ' + client.partitions[index].osName;
+ options.scope.partitions.push(obj);
+ }
+ }
+
+ this.ogSweetAlert.swal({
+ title: this.translate.instant('select_partition_to_inventary'),
+ // text: $filter("translate")("action_cannot_be_undone"),
+ type: 'info',
+ input: 'select',
+ inputOptions: options.scope.partitions,
+ showCancelButton: true,
+ confirmButtonColor: '#3c8dbc',
+ confirmButtonText: this.translate.instant('done'),
+ closeOnConfirm: true
+ }).then(
+ function(result) {
+ if (result.value) {
+ // Montar el script con el disco y partición elegida
+ this.execution.script = this.commands.SOFTWARE_INVENTORY + ' ' + result.value;
+ this.loadClients();
+ this.sendCommand();
+ }
+ },
+ null);
+ } else {
+ if (command === 'REBOOT') {
+ this.execution.script = environment.commands.REBOOT;
+ } else if (command === 'POWER_OFF') {
+ this.execution.script = environment.commands.POWER_OFF;
+ } else if (command === 'POWER_ON') {
+ this.execution.script = 'wakeonlan';
+ } else if (command === 'HARDWARE_INVENTORY') {
+ this.execution.script = environment.commands.HARDWARE_INVENTORY;
+ } else if (command === 'RUN_SCRIPT') {
+ this.execution.script = params ? (params.script || this.ogInstructions) : this.ogInstructions;
+ } else if (command === 'REFRESH_INFO') {
+ this.execution.script = environment.commands.REFRESH_INFO;
+ }
+
+ // Comprobar si en los parametros viene la opcion de guardar
+ if (typeof params !== 'undefined' && params.save === true) {
+ const self = this;
+ // Mostrar cuadro de dialogo para guardar procedimiento
+ this.ogSweetAlert.swal({
+ title: this.translate.instant('new_command_name'),
+ type: 'info',
+ html:
+ '<form style="text-align: left; padding-left: 10px">\
+ <div class="form-group">\
+ <label for="execute">' + this.translate.instant('execute') + '</label>\
+ <div class="checkbox clip-check check-primary checkbox-inline">\
+ <input id="execute" icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" />\
+ </div>\
+ </div>\
+ <div class="form-group">\
+ <label>' + this.translate.instant('title') + '</label>\
+ <input type="text" class="form-control" id="command.title" />\
+ </div>\
+ <div class="form-group">\
+ <label for="parameters">' + this.translate.instant('parameters') + '</label>\
+ <div class="checkbox clip-check check-primary checkbox-inline">\
+ <input id="parameters" icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" />\
+ </div>\
+ <p class="help-block">' + this.translate.instant('help_command_parameters') + '</p>\
+ </div>\
+ </form>',
+ showCancelButton: true,
+ confirmButtonColor: '#3c8dbc',
+ confirmButtonText: this.translate.instant('done'),
+ closeOnConfirm: true,
+ preConfirm: () => {
+ return {
+ execute: (<HTMLInputElement>document.getElementById('execute')).checked,
+ command: {
+ title: (<HTMLInputElement>document.getElementById('command.title')).value,
+ parameters: (<HTMLInputElement>document.getElementById('parameters')).checked
+ }
+ };
+ }
+ }).then(
+ function(response) {
+ if (response.value) {
+ response.value.command.script = self.execution.script;
+ response.value.command.type = self.execution.type;
+ self.commandService.create(response.value.command).subscribe(
+ (success) => {
+ // Si se seleccionó continuar con la ejecución
+ if (response.value.execute) {
+ self.loadClients();
+ self.sendCommand();
+ } else {
+ self.router.navigate(['app/commands']);
+ }
+ },
+ (error) => {
+ self.toaster.pop({type: 'error', title: 'error', body: error});
+ }
+ );
+ }
+ });
+ } else {
+ this.loadClients();
+ this.sendCommand();
+ }
+ }
+ }
+
+ loadClients() {
+ if (this.ogCommonService.selectedClients) {
+ this.execution.clients = _.join(Object.keys(this.ogCommonService.selectedClients));
+ }
+ }
+
+}
diff --git a/admin/WebConsole3/frontend/src/app/service/og-common.service.ts b/admin/WebConsole3/frontend/src/app/service/og-common.service.ts
index ee5a8a9d..8a2bbe56 100644
--- a/admin/WebConsole3/frontend/src/app/service/og-common.service.ts
+++ b/admin/WebConsole3/frontend/src/app/service/og-common.service.ts
@@ -42,7 +42,8 @@ export class OgCommonService {
ou: environment.ou,
themes: environment.themes,
menus: environment.menus,
- languages: environment.languages
+ languages: environment.languages,
+ deployMethods: environment.deployMethods
};
this.constants = Object.assign(this.constants, data[0]);
// inicializar timers generales para refresco de información
diff --git a/admin/WebConsole3/frontend/src/styles.scss b/admin/WebConsole3/frontend/src/styles.scss
index 57a04153..65c2fd6d 100644
--- a/admin/WebConsole3/frontend/src/styles.scss
+++ b/admin/WebConsole3/frontend/src/styles.scss
@@ -1,4 +1,8 @@
/* You can add global styles to this file, and also import other style files */
+.input-group {
+ width: 100%;
+}
+
.capitalize {
text-transform: capitalize;
}