Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 0 additions & 40 deletions app/components/base/form/form-base.component.ts

This file was deleted.

1 change: 0 additions & 1 deletion app/components/base/form/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from "./form.module";
export * from "./form-base.component";
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { Observable } from "rxjs";
import { NotificationService } from "app/components/base/notifications";
import { SidebarRef } from "app/components/base/sidebar";
import { RangeValidatorDirective } from "app/components/base/validation";
import { DynamicForm } from "app/core";
import { Job, Pool } from "app/models";
import { JobCreateDto } from "app/models/dtos";
import { createJobFormToJsonData, jobToFormModel } from "app/models/forms";
import { JobService, PoolService } from "app/services";
import { RxListProxy } from "app/services/core";
Expand All @@ -16,9 +18,8 @@ import { Constants } from "app/utils";
selector: "bl-job-create-basic-dialog",
templateUrl: "job-create-basic-dialog.html",
})
export class JobCreateBasicDialogComponent implements OnInit {
export class JobCreateBasicDialogComponent extends DynamicForm<Job, JobCreateDto> implements OnInit {
public poolsData: RxListProxy<{}, Pool>;
public createJobForm: FormGroup;
public constraintsGroup: FormGroup;
public poolInfoGroup: FormGroup;

Expand All @@ -28,6 +29,7 @@ export class JobCreateBasicDialogComponent implements OnInit {
private jobService: JobService,
private poolService: PoolService,
private notificationService: NotificationService) {
super(JobCreateDto);

this.poolsData = this.poolService.list();
const validation = Constants.forms.validation;
Expand All @@ -42,7 +44,7 @@ export class JobCreateBasicDialogComponent implements OnInit {
poolId: ["", Validators.required],
});

this.createJobForm = this.formBuilder.group({
this.form = this.formBuilder.group({
id: ["", [
Validators.required,
Validators.maxLength(validation.maxLength.id),
Expand All @@ -61,22 +63,26 @@ export class JobCreateBasicDialogComponent implements OnInit {
public ngOnInit() {
this.poolsData.fetchNext().subscribe((result) => {
if (result.data && result.data.length > 0) {
this.createJobForm.value.poolId = result.data[0].id;
this.form.value.poolId = result.data[0].id;
}
});
}

public setValue(job: Job) {
this.createJobForm.patchValue(jobToFormModel(job));
public dtoToForm(job: JobCreateDto) {
return jobToFormModel(job);
}

public formToDto(data: any): JobCreateDto {
return createJobFormToJsonData(data);
}

@autobind()
public submit(): Observable<any> {
const jsonData = createJobFormToJsonData(this.createJobForm.value);
const observable = this.jobService.add(jsonData, {});
const job = this.getCurrentValue();
const observable = this.jobService.add(job, {});
observable.subscribe({
next: () => {
const id = this.createJobForm.value.id;
const id = job.id;
this.jobService.onJobAdded.next(id);
this.notificationService.success("Job added!", `Job '${id}' was created successfully!`);
},
Expand All @@ -87,6 +93,6 @@ export class JobCreateBasicDialogComponent implements OnInit {
}

public preSelectPool(poolId: string) {
this.createJobForm.patchValue({ poolInfo: { poolId } });
this.form.patchValue({ poolInfo: { poolId } });
}
}
4 changes: 2 additions & 2 deletions app/components/job/action/add/job-create-basic-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<h1>Create job</h1>
<p>Adds a job to the selected account</p>

<bl-create-form [formGroup]="createJobForm" [submit]="submit" [sidebarRef]="sidebarRef">
<form novalidate [formGroup]="createJobForm">
<bl-create-form [formGroup]="form" [submit]="submit" [sidebarRef]="sidebarRef">
<form novalidate [formGroup]="form">
<div class="form-element">
<md-input-container>

Expand Down
2 changes: 1 addition & 1 deletion app/components/job/details/job-details.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class JobDetailsComponent implements OnInit, OnDestroy {

public cloneJob() {
const ref = this.sidebarManager.open("add-basic-pool", JobCreateBasicDialogComponent);
ref.component.setValue(this.job);
ref.component.setValueFromEntity(this.job);
}

public enableJob() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { Observable } from "rxjs";

import { NotificationService } from "app/components/base/notifications";
import { SidebarRef } from "app/components/base/sidebar";
import { DynamicForm } from "app/core";
import { Pool } from "app/models";
import { PoolCreateDto } from "app/models/dtos";
import { createPoolToData, poolToFormModel } from "app/models/forms";
import { PoolService } from "app/services";

@Component({
selector: "bl-pool-create-basic-dialog",
templateUrl: "pool-create-basic-dialog.html",
})
export class PoolCreateBasicDialogComponent {
export class PoolCreateBasicDialogComponent extends DynamicForm<Pool, PoolCreateDto> {
public selectedOsConfiguration: string;
public createPoolForm: FormGroup;

Expand All @@ -27,9 +29,10 @@ export class PoolCreateBasicDialogComponent {
public sidebarRef: SidebarRef<PoolCreateBasicDialogComponent>,
private poolService: PoolService,
private notificationService: NotificationService) {
super(PoolCreateDto);

this.selectedOsConfiguration = this.OS_CONFIGURATION_TYPES.PaaS;
this.createPoolForm = this.formBuilder.group({
this.form = this.formBuilder.group({
id: ["", [
Validators.required,
Validators.maxLength(64),
Expand All @@ -46,8 +49,8 @@ export class PoolCreateBasicDialogComponent {

@autobind()
public submit(): Observable<any> {
const id = this.createPoolForm.value.id;
const data = createPoolToData(this.createPoolForm.value);
const id = this.form.value.id;
const data = this.getCurrentValue();
const obs = this.poolService.add(data);
obs.do(() => {
this.poolService.onPoolAdded.next(id);
Expand All @@ -61,8 +64,12 @@ export class PoolCreateBasicDialogComponent {
return this.getVmSizes();
}

public setValue(pool: Pool) {
this.createPoolForm.patchValue(poolToFormModel(pool));
public dtoToForm(pool: PoolCreateDto) {
return poolToFormModel(pool);
}

public formToDto(data: any): PoolCreateDto {
return createPoolToData(data);
}

// TODO: Make this into it's own component
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="slideout-form content-wrapper">
<h1>Add a pool to the account</h1>
<p>Pools allow you to provision compute nodes to do work</p>
<bl-create-form [formGroup]="createPoolForm" [submit]="submit" [sidebarRef]="sidebarRef">
<form novalidate [formGroup]="createPoolForm">
<bl-create-form [formGroup]="form" [submit]="submit" [sidebarRef]="sidebarRef">
<form novalidate [formGroup]="form">
<div class="form-element">
<md-input-container>
<input mdInput #idInput formControlName="id" placeholder="Id" maxlength="64">
Expand Down
2 changes: 1 addition & 1 deletion app/components/pool/details/pool-details.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class PoolDetailsComponent implements OnInit, OnDestroy {

public clonePool() {
const ref = this.sidebarManager.open("add-basic-pool", PoolCreateBasicDialogComponent);
ref.component.setValue(this.pool);
ref.component.setValueFromEntity(this.pool);
}

public resizePool() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class RerunTaskFormComponent extends TaskCreateBasicDialogComponent {

return ObservableUtils.queue(
() => this.taskService.delete(this.jobId, id).catch(() => Observable.of({})),
() => super.execute(),
() => super.submit(),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Component } from "@angular/core";
import { FormArray, FormBuilder, FormGroup, Validators } from "@angular/forms";
import { autobind } from "core-decorators";
import { Observable } from "rxjs";

import { FormBaseComponent } from "app/components/base/form";
import { NotificationService } from "app/components/base/notifications";
import { SidebarRef } from "app/components/base/sidebar";
import { RangeValidatorDirective } from "app/components/base/validation";
import { DynamicForm } from "app/core";
import { Task } from "app/models";
import { CreateTaskModel } from "app/models/forms";
import { TaskCreateDto } from "app/models/dtos";
import { createTaskFormToJsonData, taskToFormModel } from "app/models/forms";
import { TaskService } from "app/services";
import { Constants } from "app/utils";
Expand All @@ -16,7 +17,7 @@ import { Constants } from "app/utils";
selector: "bl-task-create-basic-dialog",
templateUrl: "task-create-basic-dialog.html",
})
export class TaskCreateBasicDialogComponent extends FormBaseComponent<Task, CreateTaskModel> {
export class TaskCreateBasicDialogComponent extends DynamicForm<Task, TaskCreateDto> {
public jobId: string;
public constraintsGroup: FormGroup;
public resourceFiles: FormArray;
Expand All @@ -31,7 +32,7 @@ export class TaskCreateBasicDialogComponent extends FormBaseComponent<Task, Crea
private sidebarRef: SidebarRef<TaskCreateBasicDialogComponent>,
protected taskService: TaskService,
private notificationService: NotificationService) {
super();
super(TaskCreateDto);

const validation = Constants.forms.validation;
this.constraintsGroup = this.formBuilder.group({
Expand All @@ -55,13 +56,21 @@ export class TaskCreateBasicDialogComponent extends FormBaseComponent<Task, Crea
});
}

public execute(): Observable<any> {
const value = this.form.getRawValue();
const id = value.id;
public dtoToForm(task: TaskCreateDto) {
return taskToFormModel(task);
}

public formToDto(data: any): TaskCreateDto {
return createTaskFormToJsonData(data);
}

@autobind()
public submit(): Observable<any> {
const task = this.getCurrentValue();
const id = task.id;

const jsonData = createTaskFormToJsonData(value);
const onAddedParams = { jobId: this.jobId, id };
const observable = this.taskService.add(this.jobId, jsonData, {});
const observable = this.taskService.add(this.jobId, task, {});
observable.subscribe({
next: () => {
this.notificationService.success("Task added!", `Task '${id}' was created successfully!`);
Expand All @@ -72,8 +81,4 @@ export class TaskCreateBasicDialogComponent extends FormBaseComponent<Task, Crea

return observable;
}

protected entityToForm(task: Task) {
return taskToFormModel(task);
}
}
2 changes: 1 addition & 1 deletion app/components/task/details/task-details.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class TaskDetailsComponent implements OnInit, OnDestroy {
public cloneTask() {
const ref = this.sidebarManager.open("add-basic-pool", TaskCreateBasicDialogComponent);
ref.component.jobId = this.jobId;
ref.component.patchValue(this.task);
ref.component.setValueFromEntity(this.task);
}

public update() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ export class TaskErrorDisplayComponent {
public rerunDifferent() {
const ref = this.sidebarManager.open("rerun-task", RerunTaskFormComponent);
ref.component.jobId = this.jobId;
ref.component.patchValue(this.task);
ref.component.setValueFromEntity(this.task);
}
}
68 changes: 68 additions & 0 deletions app/core/dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { nil } from "app/utils";

const primitives = new Set(["Array", "Number", "String", "Object", "Boolean"]);

const attrMetadataKey = "dto:attrs";

function metadataForDto<T>(dto: Dto<T>) {
return Reflect.getMetadata(attrMetadataKey, dto.constructor) || {};
}
/**
* Dto should be the base class for all dto.
* It will only assign defined attributes.
*/
export class Dto<T> {
constructor(data: AttrOf<T>) {
const attrs = metadataForDto(this);
for (let key of Object.keys(attrs)) {
const type = attrs[key];
if (!(key in data)) {
continue;
}
const value = (data as any)[key];
if (nil(value)) {
continue;
}

if (type && !primitives.has(type.name)) {
this[key] = new type(value);
} else {
this[key] = value;
}
}
}

public toJS?(): AttrOf<T> {
let output: any = {};
const attrs = metadataForDto(this);
for (let key of Object.keys(attrs)) {
if (!(key in this)) {
continue;
}
const value = this[key];
if (nil(value)) {
continue;
}
if (value.toJS) {
output[key] = value.toJS();
} else {
output[key] = value;
}
}
return output;
}
}

export function DtoAttr<T>() {
return (target, attr, descriptor?: TypedPropertyDescriptor<T>) => {
const ctr = target.constructor;
const type = Reflect.getMetadata("design:type", target, attr);
if (!type) {
throw `Cannot retrieve the type for DtoAttr ${target.constructor.name}#${attr}`
+ "Check your nested type is defined in another file or above this DtoAttr";
}
const metadata = Reflect.getMetadata(attrMetadataKey, ctr) || {};
metadata[attr] = type;
Reflect.defineMetadata(attrMetadataKey, metadata, ctr);
};
}
Loading