Save some unknown progress
This commit is contained in:
parent
ae8b16c825
commit
1aad0d7219
1
TODO.txt
Normal file
1
TODO.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
- Add route guards to make it nicer for the user if he is not logged in
|
|
@ -4,8 +4,13 @@ import {Routes, RouterModule} from '@angular/router';
|
||||||
import {DomainsComponent} from './pages/domains/domains.component';
|
import {DomainsComponent} from './pages/domains/domains.component';
|
||||||
import {UsersComponent} from './pages/users/users.component';
|
import {UsersComponent} from './pages/users/users.component';
|
||||||
import {LoginComponent} from './pages/login/login.component';
|
import {LoginComponent} from './pages/login/login.component';
|
||||||
|
import {RecordEditComponent} from './pages/record-edit/record-edit.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'domains/edit/:id',
|
||||||
|
component: RecordEditComponent
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'domains',
|
path: 'domains',
|
||||||
component: DomainsComponent
|
component: DomainsComponent
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import { FormsModule } from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import { NgModule } from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import { HttpModule } from '@angular/http';
|
import {HttpModule} from '@angular/http';
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import {AppRoutingModule} from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import {AppComponent} from './app.component';
|
||||||
|
|
||||||
import { NavbarComponent } from './partials/navbar/navbar.component';
|
import {NavbarComponent} from './partials/navbar/navbar.component';
|
||||||
import { NavbarEntryComponent } from './partials/navbar-entry/navbar-entry.component';
|
import {NavbarEntryComponent} from './partials/navbar-entry/navbar-entry.component';
|
||||||
import { FaIconComponent } from './partials/fa-icon/fa-icon.component';
|
import {FaIconComponent} from './partials/fa-icon/fa-icon.component';
|
||||||
import { AlertComponent } from './partials/alert/alert.component';
|
import {AlertComponent} from './partials/alert/alert.component';
|
||||||
import { AlertMessageComponent } from './partials/alert-message/alert-message.component';
|
import {AlertMessageComponent} from './partials/alert-message/alert-message.component';
|
||||||
import { ModalContainerComponent } from './partials/modal-container/modal-container.component';
|
import {ModalContainerComponent} from './partials/modal-container/modal-container.component';
|
||||||
import { SortComponent } from './partials/sort/sort.component';
|
import {SortComponent} from './partials/sort/sort.component';
|
||||||
|
|
||||||
import { DomainsComponent } from './pages/domains/domains.component';
|
import {DomainsComponent} from './pages/domains/domains.component';
|
||||||
import { UsersComponent } from './pages/users/users.component';
|
import {UsersComponent} from './pages/users/users.component';
|
||||||
import { LoginComponent } from './pages/login/login.component';
|
import {LoginComponent} from './pages/login/login.component';
|
||||||
|
import {RecordEditComponent} from './pages/record-edit/record-edit.component';
|
||||||
|
|
||||||
import { HttpService } from './services/http/http.service';
|
import {HttpService} from './services/http/http.service';
|
||||||
import { ModalService } from './services/modal/modal.service';
|
import {ModalService} from './services/modal/modal.service';
|
||||||
import { SessionService } from './services/session/session.service';
|
import {SessionService} from './services/session/session.service';
|
||||||
import { DomainsService } from './services/domains/domains.service';
|
import {DomainsService} from './services/domains/domains.service';
|
||||||
|
import {RecordEditService} from './services/record-edit/record-edit.service';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -35,7 +37,8 @@ import { DomainsService } from './services/domains/domains.service';
|
||||||
AlertComponent,
|
AlertComponent,
|
||||||
AlertMessageComponent,
|
AlertMessageComponent,
|
||||||
ModalContainerComponent,
|
ModalContainerComponent,
|
||||||
SortComponent
|
SortComponent,
|
||||||
|
RecordEditComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -43,7 +46,11 @@ import { DomainsService } from './services/domains/domains.service';
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule
|
HttpModule
|
||||||
],
|
],
|
||||||
providers: [SessionService, HttpService, DomainsService, ModalService],
|
providers: [SessionService,
|
||||||
|
HttpService,
|
||||||
|
DomainsService,
|
||||||
|
ModalService,
|
||||||
|
RecordEditService],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule {}
|
||||||
|
|
3
frontend/src/app/interfaces/domain-name-answer.ts
Normal file
3
frontend/src/app/interfaces/domain-name-answer.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export interface DomainNameAnswer {
|
||||||
|
name: string
|
||||||
|
}
|
|
@ -37,7 +37,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let domain of data.data">
|
<tr *ngFor="let domain of data.data" (click)="onClickDomain(domain.id)">
|
||||||
<td>{{domain.id}}</td>
|
<td>{{domain.id}}</td>
|
||||||
<td>{{domain.name}}</td>
|
<td>{{domain.name}}</td>
|
||||||
<td>{{domain.type}}</td>
|
<td>{{domain.type}}</td>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||||
|
import {Router, ActivatedRoute} from '@angular/router';
|
||||||
|
|
||||||
import { DomainsService } from 'app/services/domains/domains.service';
|
import {DomainsService} from 'app/services/domains/domains.service';
|
||||||
import { DomainsAnswer } from 'app/interfaces/domains-answer';
|
import {DomainsAnswer} from 'app/interfaces/domains-answer';
|
||||||
import { ModalService } from 'app/services/modal/modal.service';
|
import {ModalService} from 'app/services/modal/modal.service';
|
||||||
import { SortComponent } from 'app/partials/sort/sort.component';
|
import {SortComponent} from 'app/partials/sort/sort.component';
|
||||||
import { SortEvent } from 'app/interfaces/sort-event';
|
import {SortEvent} from 'app/interfaces/sort-event';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-domains',
|
selector: 'app-domains',
|
||||||
|
@ -13,7 +14,7 @@ import { SortEvent } from 'app/interfaces/sort-event';
|
||||||
})
|
})
|
||||||
export class DomainsComponent implements OnInit {
|
export class DomainsComponent implements OnInit {
|
||||||
|
|
||||||
data: DomainsAnswer = { pages: { current: 1, total: 1 }, data: [] };
|
data: DomainsAnswer = {pages: {current: 1, total: 1}, data: []};
|
||||||
|
|
||||||
@ViewChild('sortId') sortId: SortComponent;
|
@ViewChild('sortId') sortId: SortComponent;
|
||||||
@ViewChild('sortName') sortName: SortComponent;
|
@ViewChild('sortName') sortName: SortComponent;
|
||||||
|
@ -27,7 +28,9 @@ export class DomainsComponent implements OnInit {
|
||||||
private searchType = 'none';
|
private searchType = 'none';
|
||||||
|
|
||||||
constructor(private domainsService: DomainsService,
|
constructor(private domainsService: DomainsService,
|
||||||
private modalService: ModalService) { }
|
private modalService: ModalService,
|
||||||
|
private router: Router,
|
||||||
|
private route: ActivatedRoute) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.loadDomains();
|
this.loadDomains();
|
||||||
|
@ -56,7 +59,7 @@ export class DomainsComponent implements OnInit {
|
||||||
deleteDomain(id: number, name: string) {
|
deleteDomain(id: number, name: string) {
|
||||||
this.modalService.showMessage({
|
this.modalService.showMessage({
|
||||||
heading: 'Delete Domain?',
|
heading: 'Delete Domain?',
|
||||||
body: `Are you shure you want to delete the zone ${ name }?`,
|
body: `Are you shure you want to delete the zone ${name}?`,
|
||||||
acceptText: 'Delete',
|
acceptText: 'Delete',
|
||||||
dismisText: 'Cancel',
|
dismisText: 'Cancel',
|
||||||
acceptClass: 'danger'
|
acceptClass: 'danger'
|
||||||
|
@ -91,4 +94,13 @@ export class DomainsComponent implements OnInit {
|
||||||
this.loadDomains();
|
this.loadDomains();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to the domain edit page
|
||||||
|
*
|
||||||
|
* @param id Id of the domain to edit
|
||||||
|
*/
|
||||||
|
onClickDomain(id: Number) {
|
||||||
|
this.router.navigate(['edit', id], {relativeTo: this.route});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2>{{domainName}}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h3>SOA</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<form>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-primary" class="control-label">Primary</label>
|
||||||
|
<input type="text" class="form-control" id="soa-primary" placeholder="Primary" autocomplete="off" data-regex="^([^.]+\.)*[^.]+$" tabindex="1">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-mail" class="control-label">Email</label>
|
||||||
|
<input type="text" class="form-control" id="soa-mail" placeholder="Email" autocomplete="off" data-regex="^.+@[^.]+(\.[^.]+)*$" tabindex="2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6 col-md-3 col-lg-2 offset-lg-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-refresh" class="control-label">Refresh</label>
|
||||||
|
<input type="text" class="form-control" id="soa-refresh" placeholder="Refresh" autocomplete="off" data-regex="^[0-9]+$" tabindex="3">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-retry" class="control-label">Retry</label>
|
||||||
|
<input type="text" class="form-control" id="soa-retry" placeholder="Retry" autocomplete="off" data-regex="^[0-9]+$" tabindex="4">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6 col-md-3 col-lg-2 offset-lg-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-expire" class="control-label">Expire</label>
|
||||||
|
<input type="text" class="form-control" id="soa-expire" placeholder="Expire" autocomplete="off" data-regex="^[0-9]+$" tabindex="5">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-ttl" class="control-label">TTL</label>
|
||||||
|
<input type="text" class="form-control" id="soa-ttl" placeholder="TTL" autocomplete="off" data-regex="^[0-9]+$" tabindex="6">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6 col-md-2 col-lg-2 offset-lg-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="soa-serial" class="control-label">Serial</label>
|
||||||
|
<input type="text" class="form-control" id="soa-serial" placeholder="Serial" disabled data-regex=".*">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<button disabled type="submit" class="btn btn-primary" tabindex="7">Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RecordEditComponent } from './record-edit.component';
|
||||||
|
|
||||||
|
describe('RecordEditComponent', () => {
|
||||||
|
let component: RecordEditComponent;
|
||||||
|
let fixture: ComponentFixture<RecordEditComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ RecordEditComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RecordEditComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
29
frontend/src/app/pages/record-edit/record-edit.component.ts
Normal file
29
frontend/src/app/pages/record-edit/record-edit.component.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {ActivatedRoute, ParamMap} from '@angular/router';
|
||||||
|
|
||||||
|
import {RecordEditService} from 'app/services/record-edit/record-edit.service';
|
||||||
|
import {DomainNameAnswer} from 'app/interfaces/domain-name-answer';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-record-edit',
|
||||||
|
templateUrl: './record-edit.component.html',
|
||||||
|
styleUrls: ['./record-edit.component.scss']
|
||||||
|
})
|
||||||
|
export class RecordEditComponent implements OnInit {
|
||||||
|
|
||||||
|
private domainName = '';
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private recordEditService: RecordEditService) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.route.paramMap.subscribe((params: ParamMap) => {
|
||||||
|
this.initDomain(parseInt(params.get('id'), 10));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async initDomain(id: number) {
|
||||||
|
this.domainName = (await this.recordEditService.getDomainName(id)).name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RecordEditService } from './record-edit.service';
|
||||||
|
|
||||||
|
describe('RecordEditService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [RecordEditService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([RecordEditService], (service: RecordEditService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
34
frontend/src/app/services/record-edit/record-edit.service.ts
Normal file
34
frontend/src/app/services/record-edit/record-edit.service.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
|
||||||
|
import {HttpService} from 'app/services/http/http.service';
|
||||||
|
import {DomainNameAnswer} from 'app/interfaces/domain-name-answer';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RecordEditService {
|
||||||
|
|
||||||
|
constructor(private httpService: HttpService) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the domain
|
||||||
|
*
|
||||||
|
* @param id Id of the domain for which the name should be retrieved
|
||||||
|
*
|
||||||
|
* @returns A Promise for a DomainNameAnswer
|
||||||
|
*/
|
||||||
|
getDomainName(id: number): Promise<DomainNameAnswer> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const body = {
|
||||||
|
action: 'getDomainName',
|
||||||
|
domain: id
|
||||||
|
};
|
||||||
|
|
||||||
|
this.httpService.post<DomainNameAnswer>('api/edit-master.php', body)
|
||||||
|
.then((answer: DomainNameAnswer) => {
|
||||||
|
resolve(answer);
|
||||||
|
}, (err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue