Added domains page
This commit is contained in:
parent
d1a32ec860
commit
43b911eb60
16
frontend/src/app/apitypes/Domain.apitype.ts
Normal file
16
frontend/src/app/apitypes/Domain.apitype.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
export class DomainApitype {
|
||||||
|
|
||||||
|
public id = 0;
|
||||||
|
|
||||||
|
public name = '';
|
||||||
|
|
||||||
|
public type = '';
|
||||||
|
|
||||||
|
public master: string = null;
|
||||||
|
|
||||||
|
public records = 0;
|
||||||
|
|
||||||
|
constructor(init: Object) {
|
||||||
|
Object.assign(this, init);
|
||||||
|
}
|
||||||
|
}
|
12
frontend/src/app/apitypes/List.apitype.ts
Normal file
12
frontend/src/app/apitypes/List.apitype.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { PagingApitype } from './Paging.apitype';
|
||||||
|
|
||||||
|
export class ListApitype<T> {
|
||||||
|
|
||||||
|
public paging: PagingApitype;
|
||||||
|
|
||||||
|
public results: T[] = [];
|
||||||
|
|
||||||
|
constructor(init: Object) {
|
||||||
|
Object.assign(this, init);
|
||||||
|
}
|
||||||
|
}
|
12
frontend/src/app/apitypes/Paging.apitype.ts
Normal file
12
frontend/src/app/apitypes/Paging.apitype.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export class PagingApitype {
|
||||||
|
|
||||||
|
public page = 1;
|
||||||
|
|
||||||
|
public total = 1;
|
||||||
|
|
||||||
|
public pagesize: number = null;
|
||||||
|
|
||||||
|
constructor(init: Object) {
|
||||||
|
Object.assign(this, init);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { PagesizeComponent } from './partials/pagesize/pagesize.component';
|
||||||
|
import { PagingComponent } from './partials/paging/paging.component';
|
||||||
|
import { DomainsOperation } from './operations/domains.operations';
|
||||||
import { PasswordOperation } from './operations/password.operations';
|
import { PasswordOperation } from './operations/password.operations';
|
||||||
import { AuthGuard } from './services/auth-guard.service';
|
import { AuthGuard } from './services/auth-guard.service';
|
||||||
import { FocusDirective } from './utils/Focus.directive';
|
import { FocusDirective } from './utils/Focus.directive';
|
||||||
|
@ -21,6 +24,7 @@ import { HttpService } from './services/http.service';
|
||||||
import { SessionOperation } from './operations/session.operation';
|
import { SessionOperation } from './operations/session.operation';
|
||||||
import { DomainsComponent } from './pages/domains/domains.component';
|
import { DomainsComponent } from './pages/domains/domains.component';
|
||||||
import { PasswordComponent } from './pages/password/password.component';
|
import { PasswordComponent } from './pages/password/password.component';
|
||||||
|
import { EditSlaveComponent } from './pages/edit-slave/edit-slave.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -35,7 +39,10 @@ import { PasswordComponent } from './pages/password/password.component';
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
DomainsComponent,
|
DomainsComponent,
|
||||||
FocusDirective,
|
FocusDirective,
|
||||||
PasswordComponent
|
PasswordComponent,
|
||||||
|
PagingComponent,
|
||||||
|
PagesizeComponent,
|
||||||
|
EditSlaveComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -48,6 +55,7 @@ import { PasswordComponent } from './pages/password/password.component';
|
||||||
HttpService,
|
HttpService,
|
||||||
SessionOperation,
|
SessionOperation,
|
||||||
PasswordOperation,
|
PasswordOperation,
|
||||||
|
DomainsOperation,
|
||||||
AuthGuard
|
AuthGuard
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|
|
@ -11,7 +11,13 @@ export class ModalOptionsDatatype {
|
||||||
|
|
||||||
public acceptClass: 'primary';
|
public acceptClass: 'primary';
|
||||||
|
|
||||||
constructor(init: Object) {
|
constructor(init: {
|
||||||
|
heading: string
|
||||||
|
body: string
|
||||||
|
acceptText: string
|
||||||
|
dismisText: string,
|
||||||
|
acceptClass?: string
|
||||||
|
}) {
|
||||||
Object.assign(this, init);
|
Object.assign(this, init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
frontend/src/app/operations/domains.operations.ts
Normal file
35
frontend/src/app/operations/domains.operations.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { DomainApitype } from './../apitypes/Domain.apitype';
|
||||||
|
import { ListApitype } from './../apitypes/List.apitype';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpService } from '../services/http.service';
|
||||||
|
import { StateService } from '../services/state.service';
|
||||||
|
import { SessionApitype } from '../apitypes/Session.apitype';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DomainsOperation {
|
||||||
|
|
||||||
|
constructor(private http: HttpService, private gs: StateService) { }
|
||||||
|
|
||||||
|
public async getList(page?: number, pageSize?: number, query?: string, sort?: Array<String>): Promise<ListApitype<DomainApitype>> {
|
||||||
|
try {
|
||||||
|
return new ListApitype<DomainApitype>(await this.http.get('/domains', {
|
||||||
|
page: page,
|
||||||
|
pagesize: pageSize,
|
||||||
|
query: query
|
||||||
|
}));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return new ListApitype<DomainApitype>({ paging: {}, results: [] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async delete(domainId: number): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await this.http.delete(['/domains', domainId.toString()]);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,30 @@
|
||||||
<p>
|
<app-pagesize [pagesizes]="gs.pageSizes" [currentPagesize]="gs.pageSize" (pagesizeChange)="onPagesizeChange($event)"></app-pagesize>
|
||||||
domains works!
|
<div class="row">
|
||||||
</p>
|
<div class="col-12">
|
||||||
|
<div class="table-responsive-lg">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-5">ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th class="w-25">Type</th>
|
||||||
|
<th class="w-15">Records</th>
|
||||||
|
<th *ngIf="gs.isAdmin" class="w-5"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let domain of domainList" class="cursor-pointer" (click)="onDomainClick(domain)">
|
||||||
|
<td>{{ domain.id }}</td>
|
||||||
|
<td>{{ domain.name }}</td>
|
||||||
|
<td>{{ domain.type }}</td>
|
||||||
|
<td>{{ domain.records }}</td>
|
||||||
|
<td *ngIf="gs.isAdmin">
|
||||||
|
<app-fa-icon class="cursor-pointer" icon="trash" (click)="onDeleteDomain(domain)"></app-fa-icon>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<app-paging [pagingInfo]="pagingInfo" [pageWidth]="3" (pageChange)="onPageChange($event)"></app-paging>
|
|
@ -1,12 +1,65 @@
|
||||||
import { Component } from '@angular/core';
|
import { ModalOptionsDatatype } from './../../datatypes/modal-options.datatype';
|
||||||
|
import { ModalService } from './../../services/modal.service';
|
||||||
|
import { StateService } from './../../services/state.service';
|
||||||
|
import { DomainApitype } from './../../apitypes/Domain.apitype';
|
||||||
|
import { PagingApitype } from './../../apitypes/Paging.apitype';
|
||||||
|
import { DomainsOperation } from './../../operations/domains.operations';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-domains',
|
selector: 'app-domains',
|
||||||
templateUrl: './domains.component.html',
|
templateUrl: './domains.component.html',
|
||||||
styleUrls: ['./domains.component.scss']
|
styleUrls: ['./domains.component.scss']
|
||||||
})
|
})
|
||||||
export class DomainsComponent {
|
export class DomainsComponent implements OnInit {
|
||||||
|
|
||||||
constructor() { }
|
public pagingInfo = new PagingApitype({});
|
||||||
|
public pageRequested = 1;
|
||||||
|
|
||||||
|
public domainList: DomainApitype[] = [];
|
||||||
|
|
||||||
|
constructor(private domains: DomainsOperation, public gs: StateService, private modal: ModalService) { }
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async loadData() {
|
||||||
|
const res = await this.domains.getList(this.pageRequested, this.gs.pageSize);
|
||||||
|
|
||||||
|
this.pagingInfo = res.paging;
|
||||||
|
this.domainList = res.results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onDeleteDomain(domain: DomainApitype) {
|
||||||
|
try {
|
||||||
|
await this.modal.showMessage(new ModalOptionsDatatype({
|
||||||
|
heading: 'Confirm deletion',
|
||||||
|
body: 'Are you shure you want to delete ' + domain.name + '?',
|
||||||
|
acceptText: 'Delete',
|
||||||
|
dismisText: 'Cancel',
|
||||||
|
acceptClass: 'danger'
|
||||||
|
}));
|
||||||
|
|
||||||
|
await this.domains.delete(domain.id);
|
||||||
|
|
||||||
|
await this.loadData();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onPageChange(newPage: number) {
|
||||||
|
this.pageRequested = newPage;
|
||||||
|
await this.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onPagesizeChange(pagesize: number) {
|
||||||
|
this.gs.pageSize = pagesize;
|
||||||
|
this.pageRequested = 1;
|
||||||
|
await this.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async onDomainClick(domain: DomainApitype) {
|
||||||
|
alert(domain.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<app-alert-message>Username or password is invalid!</app-alert-message>
|
<app-alert-message>Username or password is invalid!</app-alert-message>
|
||||||
</app-alert>
|
</app-alert>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-success float-right" [disabled]="!loginForm.valid">Login</button>
|
<button type="submit" class="btn btn-primary float-right" [disabled]="!loginForm.valid">Login</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<app-alert-message>Password change sucessfull.</app-alert-message>
|
<app-alert-message>Password change sucessfull.</app-alert-message>
|
||||||
</app-alert>
|
</app-alert>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-success float-right" [disabled]="!passwordForm.valid">Change</button>
|
<button type="submit" class="btn btn-primary float-right" [disabled]="!passwordForm.valid">Change</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
12
frontend/src/app/partials/pagesize/pagesize.component.html
Normal file
12
frontend/src/app/partials/pagesize/pagesize.component.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="row">
|
||||||
|
<nav class="mr-3 ml-auto">
|
||||||
|
<ul class="pagination pagination-sm">
|
||||||
|
<li class="disabled page-item">
|
||||||
|
<span class="page-link">Entries per page</span>
|
||||||
|
</li>
|
||||||
|
<li *ngFor="let i of pagesizes" class="page-item" [class.active]="i === currentPagesize" (click)="newPagesize(i)">
|
||||||
|
<span class="page-link">{{ i }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
23
frontend/src/app/partials/pagesize/pagesize.component.ts
Normal file
23
frontend/src/app/partials/pagesize/pagesize.component.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { PagingApitype } from './../../apitypes/Paging.apitype';
|
||||||
|
import { Component, Input, EventEmitter, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-pagesize',
|
||||||
|
templateUrl: './pagesize.component.html',
|
||||||
|
styleUrls: ['./pagesize.component.scss']
|
||||||
|
})
|
||||||
|
export class PagesizeComponent {
|
||||||
|
|
||||||
|
@Input() pagesizes: Array<number>;
|
||||||
|
|
||||||
|
@Input() currentPagesize: number;
|
||||||
|
|
||||||
|
@Output() pagesizeChange = new EventEmitter<number>();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public newPagesize(pagesize: number) {
|
||||||
|
this.pagesizeChange.emit(pagesize);
|
||||||
|
}
|
||||||
|
}
|
21
frontend/src/app/partials/paging/paging.component.html
Normal file
21
frontend/src/app/partials/paging/paging.component.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<div *ngIf="pagingInfo.total > 1" class="row">
|
||||||
|
<nav class="mx-auto">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li *ngIf="pagingInfo.page > 1" class="page-item" (click)="previous()">
|
||||||
|
<app-fa-icon class="page-link" icon="angle-left"></app-fa-icon>
|
||||||
|
</li>
|
||||||
|
<li *ngIf="truncatesLeft()" class="page-item disabled">
|
||||||
|
<app-fa-icon class="page-link" icon="ellipsis-h"></app-fa-icon>
|
||||||
|
</li>
|
||||||
|
<li *ngFor="let i of createNumbers()" class="page-item" [class.active]="i === pagingInfo.page" (click)="newPage(i)">
|
||||||
|
<span class="page-link">{{ i }}</span>
|
||||||
|
</li>
|
||||||
|
<li *ngIf="truncatesRight()" class="page-item disabled">
|
||||||
|
<app-fa-icon class="page-link" icon="ellipsis-h"></app-fa-icon>
|
||||||
|
</li>
|
||||||
|
<li *ngIf="pagingInfo.page < pagingInfo.total" class="page-item " (click)="next()">
|
||||||
|
<app-fa-icon class="page-link " icon="angle-right "></app-fa-icon>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
49
frontend/src/app/partials/paging/paging.component.ts
Normal file
49
frontend/src/app/partials/paging/paging.component.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import { PagingApitype } from './../../apitypes/Paging.apitype';
|
||||||
|
import { Component, Input, EventEmitter, Output } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-paging',
|
||||||
|
templateUrl: './paging.component.html',
|
||||||
|
styleUrls: ['./paging.component.scss']
|
||||||
|
})
|
||||||
|
export class PagingComponent {
|
||||||
|
|
||||||
|
@Input() pagingInfo: PagingApitype;
|
||||||
|
|
||||||
|
@Input() pageWidth = 2;
|
||||||
|
|
||||||
|
@Output() pageChange = new EventEmitter<number>();
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
public createNumbers(): Array<number> {
|
||||||
|
const min = Math.max(1, this.pagingInfo.page - this.pageWidth);
|
||||||
|
const max = Math.min(this.pagingInfo.total, this.pagingInfo.page + this.pageWidth);
|
||||||
|
|
||||||
|
const pages = [];
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public truncatesLeft(): boolean {
|
||||||
|
return this.pagingInfo.page - this.pageWidth > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public truncatesRight(): boolean {
|
||||||
|
return this.pagingInfo.page + this.pageWidth < this.pagingInfo.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public previous(): void {
|
||||||
|
this.pageChange.emit(this.pagingInfo.page - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public next(): void {
|
||||||
|
this.pageChange.emit(this.pagingInfo.page + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public newPage(page: number) {
|
||||||
|
this.pageChange.emit(page);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,10 @@ export class HttpService {
|
||||||
public async get(url: string, params: Object = {}): Promise<any> {
|
public async get(url: string, params: Object = {}): Promise<any> {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
for (const [k, v] of Object.entries(params)) {
|
for (const [k, v] of Object.entries(params)) {
|
||||||
|
if (v === undefined || v === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let value;
|
let value;
|
||||||
if (v instanceof Array) {
|
if (v instanceof Array) {
|
||||||
value = v.join(',');
|
value = v.join(',');
|
||||||
|
|
|
@ -1,53 +1,68 @@
|
||||||
|
import { SessionApitype } from './../apitypes/Session.apitype';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StateService {
|
export class StateService {
|
||||||
|
|
||||||
public _isLoggedIn = false;
|
private _isLoggedIn = false;
|
||||||
get isLoggedIn(): boolean {
|
get isLoggedIn(): boolean {
|
||||||
return this._isLoggedIn;
|
return this._isLoggedIn;
|
||||||
}
|
}
|
||||||
set isLoggedIn(_isLoggedIn: boolean) {
|
set isLoggedIn(_isLoggedIn: boolean) {
|
||||||
this._isLoggedIn = _isLoggedIn;
|
this._isLoggedIn = _isLoggedIn;
|
||||||
this.saveSessionStorage();
|
this.saveLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public _isAdmin = false;
|
private _isAdmin = false;
|
||||||
get isAdmin(): boolean {
|
get isAdmin(): boolean {
|
||||||
return this._isAdmin;
|
return this._isAdmin;
|
||||||
}
|
}
|
||||||
set isAdmin(_isAdmin: boolean) {
|
set isAdmin(_isAdmin: boolean) {
|
||||||
this._isAdmin = _isAdmin;
|
this._isAdmin = _isAdmin;
|
||||||
this.saveSessionStorage();
|
this.saveLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public _apiToken: string = null;
|
private _apiToken: string = null;
|
||||||
get apiToken(): string {
|
get apiToken(): string {
|
||||||
return this._apiToken;
|
return this._apiToken;
|
||||||
}
|
}
|
||||||
set apiToken(_apiToken: string) {
|
set apiToken(_apiToken: string) {
|
||||||
this._apiToken = _apiToken;
|
this._apiToken = _apiToken;
|
||||||
this.saveSessionStorage();
|
this.saveLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public _isNative = false;
|
private _isNative = false;
|
||||||
get isNative(): boolean {
|
get isNative(): boolean {
|
||||||
return this._isNative;
|
return this._isNative;
|
||||||
}
|
}
|
||||||
set isNative(_isNative: boolean) {
|
set isNative(_isNative: boolean) {
|
||||||
this._isNative = _isNative;
|
this._isNative = _isNative;
|
||||||
this.saveSessionStorage();
|
this.saveLocalStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _pageSize = 25;
|
||||||
|
get pageSize(): number {
|
||||||
|
return this._pageSize;
|
||||||
|
}
|
||||||
|
set pageSize(_pageSize: number) {
|
||||||
|
this._pageSize = _pageSize;
|
||||||
|
this.saveLocalStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _pageSizes = [5, 10, 25, 50, 100];
|
||||||
|
get pageSizes(): Array<number> {
|
||||||
|
return this._pageSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.loadSessiontorage();
|
this.loadLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private saveSessionStorage() {
|
private saveLocalStorage() {
|
||||||
sessionStorage.setItem('pdnsmanagerstate', JSON.stringify(this));
|
localStorage.setItem('pdnsmanagerstate', JSON.stringify(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadSessiontorage() {
|
private loadLocalStorage() {
|
||||||
Object.assign(this, JSON.parse(sessionStorage.getItem('pdnsmanagerstate')));
|
Object.assign(this, JSON.parse(localStorage.getItem('pdnsmanagerstate')));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,30 @@
|
||||||
/* Bootstrap and customizations */
|
/* Bootstrap and customizations */
|
||||||
|
$table-cell-padding: .60rem !default;
|
||||||
|
|
||||||
|
$sizes: (
|
||||||
|
0: 0%,
|
||||||
|
5: 5%,
|
||||||
|
10: 10%,
|
||||||
|
15: 15%,
|
||||||
|
20: 20%,
|
||||||
|
25: 25%,
|
||||||
|
30: 30%,
|
||||||
|
35: 35%,
|
||||||
|
40: 40%,
|
||||||
|
45: 45%,
|
||||||
|
50: 50%,
|
||||||
|
55: 55%,
|
||||||
|
60: 60%,
|
||||||
|
65: 65%,
|
||||||
|
70: 70%,
|
||||||
|
75: 75%,
|
||||||
|
80: 80%,
|
||||||
|
85: 85%,
|
||||||
|
90: 90%,
|
||||||
|
95: 95%,
|
||||||
|
100: 100%
|
||||||
|
);
|
||||||
|
|
||||||
@import '~bootstrap/scss/bootstrap.scss';
|
@import '~bootstrap/scss/bootstrap.scss';
|
||||||
|
|
||||||
/* Add font awesome */
|
/* Add font awesome */
|
||||||
|
@ -27,3 +53,8 @@ $fa-font-path: "~font-awesome/fonts";
|
||||||
.ng-dirty.ng-valid.auto-validstate {
|
.ng-dirty.ng-valid.auto-validstate {
|
||||||
@extend .is-valid;
|
@extend .is-valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cursor pointer class */
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue