import { Component, inject, signal, OnInit } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { ApiService } from '../../core/services/api.service';
import { ToastService } from '../../core/services/toast.service';
import { IServiceCreate, IDomainDetail } from '../../core/types/api.types';
import {
CardComponent,
CardHeaderComponent,
CardTitleComponent,
CardDescriptionComponent,
CardContentComponent,
CardFooterComponent,
} from '../../ui/card/card.component';
import { ButtonComponent } from '../../ui/button/button.component';
import { InputComponent } from '../../ui/input/input.component';
import { LabelComponent } from '../../ui/label/label.component';
import { CheckboxComponent } from '../../ui/checkbox/checkbox.component';
import { AlertComponent, AlertDescriptionComponent } from '../../ui/alert/alert.component';
import { SeparatorComponent } from '../../ui/separator/separator.component';
interface EnvVar {
key: string;
value: string;
}
@Component({
selector: 'app-service-create',
standalone: true,
imports: [
FormsModule,
RouterLink,
CardComponent,
CardHeaderComponent,
CardTitleComponent,
CardDescriptionComponent,
CardContentComponent,
CardFooterComponent,
ButtonComponent,
InputComponent,
LabelComponent,
CheckboxComponent,
AlertComponent,
AlertDescriptionComponent,
SeparatorComponent,
],
template: `
`,
})
export class ServiceCreateComponent implements OnInit {
private api = inject(ApiService);
private router = inject(Router);
private toast = inject(ToastService);
form: IServiceCreate = {
name: '',
image: '',
port: 80,
domain: '',
useOneboxRegistry: false,
registryImageTag: 'latest',
autoUpdateOnPush: false,
enableMongoDB: false,
enableS3: false,
};
envVars = signal([]);
domains = signal([]);
loading = signal(false);
domainWarning = signal(null);
ngOnInit(): void {
this.loadDomains();
}
async loadDomains(): Promise {
try {
const response = await this.api.getDomains();
if (response.success && response.data) {
this.domains.set(response.data);
}
} catch {
// Silent fail - domain autocomplete is optional
}
}
addEnvVar(): void {
this.envVars.update(vars => [...vars, { key: '', value: '' }]);
}
removeEnvVar(index: number): void {
this.envVars.update(vars => vars.filter((_, i) => i !== index));
}
validateDomain(): void {
if (!this.form.domain) {
this.domainWarning.set(null);
return;
}
const domain = this.domains().find(d => d.domain.domain === this.form.domain);
if (!domain) {
this.domainWarning.set('This domain is not in your domain list. DNS and SSL may not be configured automatically.');
} else if (domain.domain.isObsolete) {
this.domainWarning.set('This domain is marked as obsolete.');
} else {
this.domainWarning.set(null);
}
}
async onSubmit(): Promise {
if (!this.form.name || !this.form.image || !this.form.port) {
this.toast.error('Please fill in all required fields');
return;
}
this.loading.set(true);
// Build env vars object
const envVarsObj: Record = {};
for (const env of this.envVars()) {
if (env.key && env.value) {
envVarsObj[env.key] = env.value;
}
}
const data: IServiceCreate = {
...this.form,
envVars: Object.keys(envVarsObj).length > 0 ? envVarsObj : undefined,
};
try {
const response = await this.api.createService(data);
if (response.success) {
this.toast.success(`Service "${this.form.name}" deployed successfully`);
this.router.navigate(['/services']);
} else {
this.toast.error(response.error || 'Failed to deploy service');
}
} catch {
this.toast.error('Failed to deploy service');
} finally {
this.loading.set(false);
}
}
}