mirror of
https://github.com/akveo/ngx-admin.git
synced 2026-01-28 20:26:10 +01:00
prepare for sit. (docker)
This commit is contained in:
parent
311885894f
commit
8a39954811
39 changed files with 4819 additions and 1152 deletions
|
|
@ -1,6 +1,9 @@
|
|||
import { User } from './user';
|
||||
|
||||
export interface UserResponse {
|
||||
username: string,
|
||||
value: UserRole[],
|
||||
user: User;
|
||||
}
|
||||
|
||||
export interface UserRole {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export interface User {
|
||||
username: string,
|
||||
password: string,
|
||||
export class User {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
|
@ -5,23 +5,19 @@
|
|||
</a>
|
||||
<a class="logo" href="#" (click)="navigateHome()">symfonia</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="header-container">
|
||||
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary">
|
||||
<nb-option *ngFor="let theme of themes" [value]="theme.value"> {{ theme.name }}</nb-option>
|
||||
</nb-select>
|
||||
</div>
|
||||
|
||||
<div class="header-container">
|
||||
<nb-actions size="small">
|
||||
<nb-action class="control-item">
|
||||
<nb-search type="rotate-layout"></nb-search>
|
||||
</nb-action>
|
||||
<nb-action class="control-item" icon="bell-outline"></nb-action>
|
||||
<nb-action class="user-action" *nbIsGranted="['view', 'user']" >
|
||||
<nb-user [nbContextMenu]="userMenu"
|
||||
[onlyPicture]="userPictureOnly"
|
||||
[name]="user?.name"
|
||||
[picture]="user?.picture">
|
||||
<nb-action class="user-action" *nbIsGranted="['view', 'user']">
|
||||
<nb-user [nbContextMenu]="userMenu" [onlyPicture]="userPictureOnly" [name]="username">
|
||||
</nb-user>
|
||||
</nb-action>
|
||||
</nb-actions>
|
||||
</div>
|
||||
<button (click)="logout()" nbButton>
|
||||
Log Out
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -5,6 +5,9 @@ import { UserData } from '../../../@core/data/users';
|
|||
import { LayoutService } from '../../../@core/utils';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { User } from '../../../@core/data/user';
|
||||
import { Router } from '@angular/router';
|
||||
import { LoginService } from '../../../auth/login.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-header',
|
||||
|
|
@ -15,7 +18,9 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
userPictureOnly: boolean = false;
|
||||
user: any;
|
||||
username: any;
|
||||
roles: any;
|
||||
userpicture: any;
|
||||
|
||||
themes = [
|
||||
{
|
||||
|
|
@ -38,22 +43,30 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
|
||||
currentTheme = 'default';
|
||||
|
||||
userMenu = [ { title: 'Profile' }, { title: 'Log out' } ];
|
||||
userMenu = [{ title: 'User Role(s)' }];
|
||||
|
||||
constructor(private sidebarService: NbSidebarService,
|
||||
private menuService: NbMenuService,
|
||||
private themeService: NbThemeService,
|
||||
private userService: UserData,
|
||||
private layoutService: LayoutService,
|
||||
private breakpointService: NbMediaBreakpointsService) {
|
||||
private router: Router,
|
||||
private menuService: NbMenuService,
|
||||
private themeService: NbThemeService,
|
||||
private layoutService: LayoutService,
|
||||
private loginService: LoginService,
|
||||
private breakpointService: NbMediaBreakpointsService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.currentTheme = this.themeService.currentTheme;
|
||||
|
||||
this.userService.getUsers()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((users: any) => this.user = users.nick);
|
||||
this.username = localStorage.getItem('username');
|
||||
this.roles = localStorage.getItem('roles');
|
||||
this.userpicture = 'assets/images/eva.png';
|
||||
|
||||
if (this.username == null) {
|
||||
this.router.navigate(['/auth/login']);
|
||||
}
|
||||
|
||||
this.username = this.username.replace(/['"]+/g, '');
|
||||
|
||||
this.currentTheme = this.themeService.currentTheme;
|
||||
|
||||
const { xl } = this.breakpointService.getBreakpointsMap();
|
||||
this.themeService.onMediaQueryChange()
|
||||
|
|
@ -71,6 +84,10 @@ export class HeaderComponent implements OnInit, OnDestroy {
|
|||
.subscribe(themeName => this.currentTheme = themeName);
|
||||
}
|
||||
|
||||
logout(){
|
||||
this.loginService.logout();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { AuthGuard } from './auth/AuthGuard';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
|
|
@ -7,8 +8,13 @@ export const routes: Routes = [
|
|||
loadChildren: () => import('./pages/pages.module')
|
||||
.then(m => m.PagesModule),
|
||||
},
|
||||
{ path: '', redirectTo: 'pages', pathMatch: 'full' },
|
||||
{ path: '**', redirectTo: 'pages' },
|
||||
{
|
||||
path: 'auth',
|
||||
loadChildren: () => import('./auth/login.module')
|
||||
.then(m => m.AuthModule),
|
||||
},
|
||||
{ path: '', redirectTo: 'auth/login', pathMatch: 'full' },
|
||||
{ path: '**', redirectTo: 'auth/login' },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
|
|
|||
24
src/app/auth/AuthGuard.ts
Normal file
24
src/app/auth/AuthGuard.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { LoginService } from './login.service';
|
||||
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private router: Router,
|
||||
private accountService: LoginService
|
||||
) {}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
const user = this.accountService.userValue;
|
||||
if (user) {
|
||||
// authorised so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// not logged in so redirect to login page with the return url
|
||||
this.router.navigate(['/auth/login']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
53
src/app/auth/login.component.html
Normal file
53
src/app/auth/login.component.html
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<h1 id="title" class="title">Sign In</h1>
|
||||
|
||||
<nb-alert *ngIf="showMessages.error && errors?.length && !submitted" outline="danger" role="alert">
|
||||
<p class="alert-title"><b>Oh snap!</b></p>
|
||||
<ul class="alert-message-list">
|
||||
<li *ngFor="let error of errors" class="alert-message">{{ error }}</li>
|
||||
</ul>
|
||||
</nb-alert>
|
||||
|
||||
<nb-alert *ngIf="showMessages.success && messages?.length && !submitted" outline="success" role="alert">
|
||||
<p class="alert-title"><b>Hooray!</b></p>
|
||||
<ul class="alert-message-list">
|
||||
<li *ngFor="let message of messages" class="alert-message">{{ message }}</li>
|
||||
</ul>
|
||||
</nb-alert>
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-email">NIK:</label>
|
||||
<input nbInput fullWidth [(ngModel)]="user.username" #email="ngModel" name="nik" id="input-nik" placeholder="NIK"
|
||||
autofocus>
|
||||
<ng-container *ngIf="email.invalid && email.touched">
|
||||
<p class="caption status-danger" *ngIf="email.errors?.required">
|
||||
NIK is required!
|
||||
</p>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-password">Password:</label>
|
||||
<input nbInput fullWidth [(ngModel)]="user.password" #password="ngModel" name="password" type="password"
|
||||
id="input-password" placeholder="Password"
|
||||
[status]="password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'"
|
||||
[required]="getConfigValue('forms.validation.password.required')"
|
||||
[minlength]="getConfigValue('forms.validation.password.minLength')"
|
||||
[maxlength]="getConfigValue('forms.validation.password.maxLength')"
|
||||
[attr.aria-invalid]="password.invalid && password.touched ? true : null">
|
||||
<ng-container *ngIf="password.invalid && password.touched ">
|
||||
<p class="caption status-danger" *ngIf="password.errors?.required">
|
||||
Password is required!
|
||||
</p>
|
||||
<p class="caption status-danger" *ngIf="(password.errors?.minlength || password.errors?.maxlength)">
|
||||
Password should contains
|
||||
from {{ getConfigValue('forms.validation.password.minLength') }}
|
||||
to {{ getConfigValue('forms.validation.password.maxLength') }}
|
||||
characters
|
||||
</p>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<button nbButton fullWidth (click)="onLogin()" status="success" [disabled]="submitted"
|
||||
[class.btn-pulse]="submitted">
|
||||
Sign In
|
||||
</button>
|
||||
84
src/app/auth/login.component.ts
Normal file
84
src/app/auth/login.component.ts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
import { Component, Input, ChangeDetectorRef, Inject } from '@angular/core';
|
||||
import { NbLoginComponent, NbAuthService, NB_AUTH_OPTIONS } from '@nebular/auth';
|
||||
import { User } from '../@core/data/user';
|
||||
import { Router } from '@angular/router';
|
||||
import { LoginService } from './login.service';
|
||||
import { UserResponse } from '../@core/data/user-response';
|
||||
import { NbComponentStatus, NbGlobalPosition, NbGlobalPhysicalPosition, NbToastrService } from '@nebular/theme';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-login',
|
||||
templateUrl: './login.component.html',
|
||||
})
|
||||
export class LoginComponent extends NbLoginComponent {
|
||||
|
||||
@Input() user: User;
|
||||
|
||||
index = 1;
|
||||
destroyByClick = true;
|
||||
duration = 2000;
|
||||
hasIcon = true;
|
||||
position: NbGlobalPosition = NbGlobalPhysicalPosition.TOP_RIGHT;
|
||||
preventDuplicates = false;
|
||||
status: NbComponentStatus = 'primary';
|
||||
|
||||
title = 'Login Symfonia';
|
||||
content = `Anda tidak mempunyai akses ke Symfonia`;
|
||||
|
||||
avail: boolean = false;
|
||||
|
||||
constructor(private toastrService: NbToastrService, private authService: LoginService, service: NbAuthService,
|
||||
@Inject(NB_AUTH_OPTIONS) options: {}, cd: ChangeDetectorRef, routes: Router) {
|
||||
super(service, options, cd, routes);
|
||||
}
|
||||
|
||||
onLogin() {
|
||||
this.authService.login(this.user).subscribe((res: UserResponse) => {
|
||||
if (res.username != null) {
|
||||
for (var i = 0; i < res.value.length; i++) {
|
||||
if
|
||||
(res.value[i].resourcealias == "IDM.Symfonia") {
|
||||
this.avail = true;
|
||||
}
|
||||
}
|
||||
if (this.avail) {
|
||||
this.router.navigate(['/pages/partner-price']);
|
||||
} else if (res.value.length == 0) {
|
||||
this.makeToast(this.content);
|
||||
}
|
||||
} else {
|
||||
this.makeToast("User tidak di temukan, atau password anda salah.");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
makeToast(cont: any) {
|
||||
this.showToast(this.status, this.title, cont);
|
||||
}
|
||||
|
||||
private showToast(type: NbComponentStatus, title: string, body: string) {
|
||||
const config = {
|
||||
status: type,
|
||||
destroyByClick: this.destroyByClick,
|
||||
duration: this.duration,
|
||||
hasIcon: this.hasIcon,
|
||||
position: this.position,
|
||||
preventDuplicates: this.preventDuplicates,
|
||||
};
|
||||
const titleContent = title ? `. ${title}` : '';
|
||||
|
||||
this.index += 1;
|
||||
this.toastrService.show(
|
||||
body,
|
||||
titleContent,
|
||||
config);
|
||||
}
|
||||
|
||||
}
|
||||
85
src/app/auth/login.service.ts
Normal file
85
src/app/auth/login.service.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
||||
import { Observable, throwError, BehaviorSubject } from 'rxjs';
|
||||
import { map, catchError, tap } from 'rxjs/operators';
|
||||
import { UserResponse } from '../@core/data/user-response';
|
||||
import { User } from '../@core/data/user';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LoginService {
|
||||
private userSubject: BehaviorSubject<User>;
|
||||
public user: Observable<User>;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private http: HttpClient) {
|
||||
this.userSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('user')));
|
||||
this.user = this.userSubject.asObservable();
|
||||
}
|
||||
|
||||
public get userValue(): User {
|
||||
return this.userSubject.value;
|
||||
}
|
||||
|
||||
login(user: User): Observable<any> {
|
||||
let url = 'http://34.87.6.140:8012/api/user/getAuthorization';
|
||||
|
||||
const headers = new HttpHeaders({
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-Method': 'POST',
|
||||
});
|
||||
const options = { headers: headers };
|
||||
|
||||
console.log(JSON.stringify(user));
|
||||
console.log(url);
|
||||
|
||||
return this.http.post(url, JSON.stringify(user), options).pipe(
|
||||
map(this.extractData),
|
||||
catchError(this.handleError),
|
||||
tap(res => this.setSession(res)))
|
||||
}
|
||||
|
||||
logout() {
|
||||
// remove user from local storage and set current user to null
|
||||
localStorage.removeItem('username');
|
||||
localStorage.removeItem('roles');
|
||||
this.userSubject.next(null);
|
||||
this.router.navigate(['/auth/login']);
|
||||
}
|
||||
|
||||
public setSession(authResult) {
|
||||
// store user details and jwt token in local storage to keep user logged in between page refreshes
|
||||
localStorage.setItem('username', JSON.stringify(authResult.username));
|
||||
localStorage.setItem('roles', JSON.stringify(authResult.value));
|
||||
}
|
||||
|
||||
private extractData(body: any): UserResponse {
|
||||
console.log(JSON.stringify(body));
|
||||
let result: UserResponse;
|
||||
result = Object.assign(body);
|
||||
// this.userSubject.next(); pls find this
|
||||
// this.userSubject.next();
|
||||
return result;
|
||||
}
|
||||
|
||||
private handleError(error: HttpErrorResponse | any) {
|
||||
let errMsg: string;
|
||||
let errObj: any;
|
||||
|
||||
if (error instanceof HttpErrorResponse) {
|
||||
const err = error.message || JSON.stringify(error);
|
||||
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
|
||||
errObj = error.message;
|
||||
} else {
|
||||
errMsg = error.message ? error.message : error.toString();
|
||||
const body = error.message || '';
|
||||
errObj = body;
|
||||
}
|
||||
|
||||
return throwError(errObj);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
<h1 id="title" class="title">Sign In</h1>
|
||||
|
||||
<nb-alert *ngIf="showMessages.error && errors?.length && !submitted" outline="danger" role="alert">
|
||||
<p class="alert-title"><b>Oh snap!</b></p>
|
||||
<ul class="alert-message-list">
|
||||
<li *ngFor="let error of errors" class="alert-message">{{ error }}</li>
|
||||
</ul>
|
||||
</nb-alert>
|
||||
|
||||
<nb-alert *ngIf="showMessages.success && messages?.length && !submitted" outline="success" role="alert">
|
||||
<p class="alert-title"><b>Hooray!</b></p>
|
||||
<ul class="alert-message-list">
|
||||
<li *ngFor="let message of messages" class="alert-message">{{ message }}</li>
|
||||
</ul>
|
||||
</nb-alert>
|
||||
|
||||
<!-- (ngSubmit)="login()" -->
|
||||
<form #form="ngForm" aria-labelledby="title">
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-email">NIK:</label>
|
||||
<input nbInput fullWidth [(ngModel)]="user.email" #email="ngModel" name="nik" id="input-nik" placeholder="NIK"
|
||||
autofocus>
|
||||
<ng-container *ngIf="email.invalid && email.touched">
|
||||
<p class="caption status-danger" *ngIf="email.errors?.required">
|
||||
NIK is required!
|
||||
</p>
|
||||
<!-- <p class="caption status-danger" *ngIf="email.errors?.pattern">
|
||||
NIK should be the real one!
|
||||
</p> -->
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="form-control-group">
|
||||
<label class="label" for="input-password">Password:</label>
|
||||
<input nbInput fullWidth [(ngModel)]="user.password" #password="ngModel" name="password" type="password"
|
||||
id="input-password" placeholder="Password"
|
||||
[status]="password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'"
|
||||
[required]="getConfigValue('forms.validation.password.required')"
|
||||
[minlength]="getConfigValue('forms.validation.password.minLength')"
|
||||
[maxlength]="getConfigValue('forms.validation.password.maxLength')"
|
||||
[attr.aria-invalid]="password.invalid && password.touched ? true : null">
|
||||
<ng-container *ngIf="password.invalid && password.touched ">
|
||||
<p class="caption status-danger" *ngIf="password.errors?.required">
|
||||
Password is required!
|
||||
</p>
|
||||
<p class="caption status-danger" *ngIf="(password.errors?.minlength || password.errors?.maxlength)">
|
||||
Password should contains
|
||||
from {{ getConfigValue('forms.validation.password.minLength') }}
|
||||
to {{ getConfigValue('forms.validation.password.maxLength') }}
|
||||
characters
|
||||
</p>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- <div class="form-control-group accept-group">
|
||||
<nb-checkbox name="rememberMe" [(ngModel)]="user.rememberMe" *ngIf="rememberMe">Remember me</nb-checkbox>
|
||||
<a class="forgot-password" routerLink="../request-password">Forgot Password?</a>
|
||||
</div> -->
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<button nbButton fullWidth routerLink="pages" status="success" [disabled]="submitted || !form.valid"
|
||||
[class.btn-pulse]="submitted">
|
||||
Sign In
|
||||
</button>
|
||||
|
||||
<!-- <section *ngIf="socialLinks && socialLinks.length > 0" class="links" aria-label="Social sign in">
|
||||
Or connect with:
|
||||
<div class="socials">
|
||||
<ng-container *ngFor="let socialLink of socialLinks">
|
||||
<a *ngIf="socialLink.link"
|
||||
[attr.target]="socialLink.target"
|
||||
[attr.class]="socialLink.icon"
|
||||
[class.with-icon]="socialLink.icon">{{ socialLink.title }}</a>
|
||||
<a *ngIf="socialLink.url"
|
||||
[attr.href]="socialLink.url"
|
||||
[attr.target]="socialLink.target"
|
||||
[attr.class]="socialLink.icon"
|
||||
[class.with-icon]="socialLink.icon">{{ socialLink.title }}</a>
|
||||
</ng-container>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="another-action" aria-label="Register">
|
||||
Don't have an account? <a class="text-link" routerLink="../register">Sign Up</a>
|
||||
</section> -->
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Akveo. All Rights Reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*/
|
||||
import { Component } from '@angular/core';
|
||||
import { NbLoginComponent } from '@nebular/auth';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-login',
|
||||
templateUrl: './login.component.html',
|
||||
})
|
||||
export class LoginComponent extends NbLoginComponent {
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { map, catchError, tap } from 'rxjs/operators';
|
||||
import { UserResponse } from '../../@core/data/user-response';
|
||||
import { User } from '../../@core/data/user';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LoginService {
|
||||
constructor(private http: HttpClient) {
|
||||
}
|
||||
|
||||
login(user: User): Observable<any> {
|
||||
const url = 'http://10.170.3.190:8011/api/user/getAuthorization ';
|
||||
return this.http.post(url,JSON.stringify(user)).pipe(
|
||||
map(this.extractData),
|
||||
catchError(this.handleError),
|
||||
tap(res => this.setSession(res)),
|
||||
);
|
||||
}
|
||||
|
||||
public setSession(authResult) {
|
||||
localStorage.setItem('roles', authResult.value);
|
||||
localStorage.setItem('username', authResult.username);
|
||||
}
|
||||
|
||||
|
||||
private extractData(body: any): UserResponse {
|
||||
return Object.assign(body.promotionList);
|
||||
}
|
||||
|
||||
private handleError(error: HttpErrorResponse | any) {
|
||||
let errMsg: string;
|
||||
let errObj: any;
|
||||
|
||||
if (error instanceof HttpErrorResponse) {
|
||||
const err = error.message || JSON.stringify(error);
|
||||
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
|
||||
errObj = error.error.message;
|
||||
} else {
|
||||
errMsg = error.message ? error.message : error.toString();
|
||||
const body = error.message || '';
|
||||
errObj = body;
|
||||
}
|
||||
|
||||
return throwError(errObj);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,10 +31,4 @@ export const MENU_ITEMS: NbMenuItem[] = [
|
|||
link: '/pages/partner-branch',
|
||||
home: false,
|
||||
},
|
||||
{
|
||||
title: 'Login Page',
|
||||
icon: 'keypad-outline',
|
||||
link: '/pages/auth',
|
||||
home: true,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {PromotionComponent} from './promotion/promotion.component';
|
|||
import { PartnerPriceComponent } from './partner-price/partner-price.component';
|
||||
import {BillingComponent} from './billing/billing.component';
|
||||
import {ServiceAgreementComponent} from './service-agreement/sa.component';
|
||||
import { LoginComponent } from './auth/login.component';
|
||||
|
||||
const routes: Routes = [{
|
||||
path: '',
|
||||
|
|
@ -33,10 +32,6 @@ const routes: Routes = [{
|
|||
path: 'billing',
|
||||
component: BillingComponent,
|
||||
},
|
||||
{
|
||||
path: 'auth',
|
||||
component: LoginComponent,
|
||||
},
|
||||
],
|
||||
}];
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
Service Agreement
|
||||
</nb-card-header>
|
||||
|
||||
<!-- (createConfirm)="onCreateConfirm($event)" (editConfirm)="onCreateConfirm($event)" -->
|
||||
<nb-card-body>
|
||||
<ng2-smart-table [settings]="settings" [source]="source" (deleteConfirm)="onDeleteConfirm($event)"
|
||||
(createConfirm)="onCreateConfirm($event)" (editConfirm)="onCreateConfirm($event)"
|
||||
(userRowSelect)="openWindowForm($event)">
|
||||
</ng2-smart-table>
|
||||
</nb-card-body>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
<div class="form-group">
|
||||
<label class="label">Bill Title</label>
|
||||
<nb-card-body>
|
||||
<nb-select [(selected)]="data.billTitle">
|
||||
<nb-select>
|
||||
<nb-option value="1">Invoice</nb-option>
|
||||
<nb-option value="2">Debit Note</nb-option>
|
||||
<nb-option value="3">Surat Perintah Penagihan</nb-option>
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label class="label">VAT</label>
|
||||
<input nbInput [(ngModel)]="data.vat"> %
|
||||
<input> %
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="label">Insurance</label>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue