Commit da09ad77 by Ooh-Ao

emport import template

parent 2b7a1d84
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"cli": {
"analytics": "9ea24997-323a-4ccd-9e9d-ab32af54a3f0"
"analytics": false
},
"version": 1,
"newProjectRoot": "projects",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,7 +7,8 @@
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
"e2e": "ng e2e",
"postinstall": "ngcc"
},
"private": true,
"dependencies": {
......@@ -22,12 +23,49 @@
"@angular/platform-browser-dynamic": "^12.0.2",
"@angular/platform-server": "^12.0.2",
"@angular/router": "^12.0.2",
"@iplab/ngx-file-upload": "^2.0.6",
"@ng-bootstrap/ng-bootstrap": "^9.0.2",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"angular-notifier": "^6.0.1",
"@swimlane/ngx-charts": "^16.0.0",
"@swimlane/ngx-datatable": "^17.0.0",
"@types/quill": "1.3.6",
"angular-calendar": "^0.28.16",
"angular-datatables": "^11.1.1",
"angular-feather": "^6.0.10",
"angular-notifier": "^6.0.1",
"angularx-flatpickr": "^6.5.1",
"apexcharts": "^3.25.0",
"bootstrap": "^4.5.0",
"c3": "^0.7.18",
"calendar-utils": "^0.8.1",
"chart.js": "^2.9.3",
"chartist": "^0.11.4",
"core-js": "^3.6.5",
"crossvent": "^1.5.5",
"d3": "^4.8.0",
"d3-array": "^2.7.1",
"datatables.net": "^1.10.20",
"datatables.net-dt": "^1.10.20",
"date-fns": "^2.14.0",
"dom-autoscroller": "^2.3.4",
"dom-plane": "^1.0.2",
"dom-set": "^1.1.1",
"flatpickr": "^4.6.6",
"handlebars": "^4.7.7",
"lodash": "^4.17.19",
"ng-apexcharts": "^1.5.6",
"ng-chartist": "^4.1.0",
"ng-multiselect-dropdown": "^0.2.10",
"ng2-archwizard": "^2.1.0",
"ng2-charts": "^2.3.2",
"ng2-search-filter": "^0.5.1",
"ngx-custom-validators": "8.0.0",
"ngx-perfect-scrollbar": "^9.0.0",
"ngx-quill": "^12.0.1",
"ngx-toastr": "^12.0.0",
"pace-js": "^1.0.2",
"quill": "^1.3.7",
"rxjs": "^6.6.3",
"rxjs-compat": "^6.5.4",
"sass": "^1.29.0",
......@@ -63,4 +101,4 @@
"peerDependencies": {
"tslib": "1.10.0"
}
}
\ No newline at end of file
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { Routes } from '@angular/router';
import { FullComponent } from './layouts/full/full.component';
import { BlankComponent } from './layouts/blank/blank.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './auth.guard';
export const Approutes: Routes = [
{
path: '',
component: FullComponent,
canActivate: [AuthGuard],
children: [
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{
path: 'starter',
loadChildren: () => import('./starter/starter.module').then(m => m.StarterModule)
},
{
path: 'component',
loadChildren: () => import('./component/component.module').then(m => m.ComponentsModule)
}
]
},
{
path: '**',
redirectTo: '/login'
},
{
path: 'login',
component: LoginComponent,
}
];
{
path: '',
component: FullComponent,
// canActivate: [AuthGuard],
children: [
{ path: '', redirectTo: '/authentication/login', pathMatch: 'full' },
{
path: 'starter',
loadChildren: () => import('./starter/starter.module').then(m => m.StarterModule)
},
{
path: 'component',
loadChildren: () => import('./component/component.module').then(m => m.ComponentsModule)
},
{ path: 'apps', loadChildren: () => import('./apps/apps.module').then(m => m.AppsModule) },
]
},
{
path: '',
component: BlankComponent,
children: [
{
path: 'authentication',
loadChildren:
() => import('./authentication/authentication.module').then(m => m.AuthenticationModule)
}
]
},
{
path: '**',
redirectTo: '/authentication/404'
}
];
import * as $ from 'jquery';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { CommonModule } from '@angular/common';
import {
CommonModule
} from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { Routes, RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
//import { AgmCoreModule } from '@agm/core';
import { DataTablesModule } from 'angular-datatables';
import { NgMultiSelectDropDownModule } from 'ng-multiselect-dropdown';
import { Ng2SearchPipeModule } from 'ng2-search-filter';
import { ToastrModule } from 'ngx-toastr';
import { FullComponent } from './layouts/full/full.component';
import { BlankComponent } from './layouts/blank/blank.component';
import { FeatherModule } from 'angular-feather';
import { allIcons } from 'angular-feather/icons';
import { VerticalNavigationComponent } from './shared/vertical-header/vertical-navigation.component';
import { VerticalSidebarComponent } from './shared/vertical-sidebar/vertical-sidebar.component';
......@@ -18,12 +25,9 @@ import { BreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component';
import { HorizontalNavigationComponent } from './shared/horizontal-header/horizontal-navigation.component';
import { HorizontalSidebarComponent } from './shared/horizontal-sidebar/horizontal-sidebar.component';
import { Approutes } from './app-routing.module';
import { AppComponent } from './app.component';
import { SpinnerComponent } from './shared/spinner.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './auth.guard';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar';
......@@ -31,6 +35,7 @@ import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient } from '@angular/common/http';
export function HttpLoaderFactory(http: HttpClient) {
......@@ -39,11 +44,13 @@ export function HttpLoaderFactory(http: HttpClient) {
const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
suppressScrollX: true,
wheelSpeed: 2,
wheelSpeed: 1,
wheelPropagation: true,
minScrollbarLength: 20
};
// Select some icons (use an object, not an array)
@NgModule({
declarations: [
......@@ -55,19 +62,27 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
BreadcrumbComponent,
VerticalSidebarComponent,
HorizontalNavigationComponent,
HorizontalSidebarComponent,
LoginComponent
HorizontalSidebarComponent
],
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
FormsModule,
ToastrModule.forRoot(),
FeatherModule.pick(allIcons),
ReactiveFormsModule,
DataTablesModule,
HttpClientModule,
NgbModule,
RouterModule.forRoot(Approutes),
FeatherModule,
Ng2SearchPipeModule,
RouterModule.forRoot(Approutes, { relativeLinkResolution: 'legacy' }),
PerfectScrollbarModule,
HttpClientModule,
NgMultiSelectDropDownModule.forRoot(),
// AgmCoreModule.forRoot({ apiKey: 'AIzaSyDoliAneRffQDyA7Ul9cDk3tLe7vaU4yP8' }),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
......@@ -80,8 +95,7 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
{
provide: PERFECT_SCROLLBAR_CONFIG,
useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG
},
AuthGuard
}
],
bootstrap: [AppComponent]
})
......
import { NgModule } from '@angular/core';
import { CommonModule, DatePipe, DecimalPipe } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { CalendarModule, DateAdapter } from 'angular-calendar';
import { FlatpickrModule } from 'angularx-flatpickr';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { HttpClientModule } from '@angular/common/http';
import { QuillModule } from 'ngx-quill';
import { Ng2SearchPipeModule } from 'ng2-search-filter';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { FeatherModule } from 'angular-feather';
import { Camera, Heart, Github, Activity, Airplay, AlertCircle, AlertOctagon, AlertTriangle, AlignCenter, AlignJustify, AlignLeft, AlignRight, Anchor, Aperture, Archive, ArrowDown, ArrowDownCircle, ArrowDownLeft, ArrowDownRight, ArrowLeftCircle, ArrowLeft, ArrowRight, ArrowRightCircle, ArrowUp, ArrowUpCircle, ArrowUpLeft, ArrowUpRight, AtSign, Award, BarChart2, BarChart, BatteryCharging, Battery, BellOff, Bell, Bluetooth, Bold, BookOpen, Book, Bookmark, Box, Briefcase, Calendar, CameraOff, Cast, CheckCircle, CheckSquare, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ChevronsDown, ChevronsLeft, ChevronsRight, ChevronsUp, Chrome, Circle, Clipboard, Clock, CloudDrizzle, CloudLightning, CloudOff, CloudRain, Cloud, CloudSnow, Code, Codepen, Codesandbox, Coffee, Columns, Command, Compass, Copy, CornerDownLeft, CornerDownRight, CornerLeftDown, CornerLeftUp, CornerRightDown, CornerRightUp, CornerUpLeft, CornerUpRight, Cpu, CreditCard, Crop, Crosshair, Database, Delete, Disc, DollarSign, DownloadCloud, Download, Droplet, Edit, Edit2, Edit3, ExternalLink, EyeOff, Eye, Facebook, FastForward, Feather, Figma, FileMinus, FilePlus, FileText, File, Film, Filter, Flag, Folder, FolderMinus, FolderPlus, Framer, Frown, Gift, GitBranch, GitCommit, GitMerge, GitPullRequest, Gitlab, Globe, Grid, HardDrive, Hash, Headphones, HelpCircle, Hexagon, Home, MoreHorizontal, Image, Inbox, Info, Instagram, Italic, Key, Layers, Layout, LifeBuoy, Link, Link2, Linkedin, List, Loader, Lock, LogIn, LogOut, Mail, MapPin, Map, Maximize, Maximize2, Meh, Menu, MessageCircle, MessageSquare, Mic, MicOff, Minimize, Minimize2, MinusCircle, MinusSquare, Minus, Monitor, Moon, MoreVertical, MousePointer, Move, Music, Navigation, Navigation2, Octagon, Package, Paperclip, PauseCircle, Pause, PenTool, Percent, PhoneCall, PhoneForwarded, PhoneIncoming, PhoneMissed, Phone, PhoneOff, PhoneOutgoing, PieChart, Play, PlayCircle, Plus, PlusCircle, PlusSquare, Pocket, Power, Printer, Radio, RefreshCcw, RefreshCw, Repeat, Rewind, RotateCcw, RotateCw, Rss, Save, Scissors, Search, Send, Server, Settings, Share, Share2, Shield, ShieldOff, ShoppingBag, ShoppingCart, Shuffle, Sidebar, SkipBack, SkipForward, Slack, Slash, Sliders, Smartphone, Smile, Speaker, Square, Star, StopCircle, Sun, Sunrise, Sunset, Tablet, Tag, Target, Terminal, Thermometer, ThumbsDown, ThumbsUp, ToggleLeft, ToggleRight, Tool, Trash, Trash2, Trello, TrendingDown, TrendingUp, Triangle, Truck, Tv, Twitch, Twitter, Type, Umbrella, Underline, Unlock, Upload, UploadCloud, User, UserCheck, UserMinus, UserPlus, UserX, Users, Video, VideoOff, Voicemail, Volume, Volume1, Volume2, VolumeX, Watch, Wifi, WifiOff, Wind, XCircle, XOctagon, XSquare, X, Youtube, Zap, ZapOff, ZoomIn, ZoomOut } from 'angular-feather/icons';
import { AppsRoutes } from './apps.routing';
import { ChatComponent } from './chat/chat.component';
import { TicketsComponent } from './ticketlist/tickets.component';
import { TicketdetailsComponent } from './ticketdetails/ticketdetails.component';
import { TaskboardComponent } from './taskboard/taskboard.component';
import { FullcalendarComponent } from './fullcalendar/fullcalendar.component';
import { TodosComponent } from './todos/todos.component';
import { NotesComponent } from './notes/notes.component';
// new
import { TasksComponent } from './tasks/tasks.component';
import { ContactListComponent } from './contact-list/contact-list.component';
import { MailboxComponent } from './mail/mailbox.component';
import { ListingComponent } from './mail/listing/listing.component';
import { DetailComponent } from './mail/detail/detail.component';
import { ComposeComponent } from './mail/compose/compose.component';
import { ContactComponent } from './contact/contact.component';
import { ContactsComponent } from './contacts/contacts.component';
import { ListUsersComponent } from './users/list-users/list-users.component';
import { EditAddUserComponent } from './users/edit-add-user/edit-add-user.component';
// Job search
import { JobsListComponent } from './jobs/jobs-list/jobs-list.component';
import { JobDetailComponent } from './jobs/job-detail/job-detail.component';
import { JobApplyComponent } from './jobs/job-apply/job-apply.component';
import { ServicejobService } from './jobs/servicejob.service';
import { TicketService } from './ticketlist/tickets.service';
import { TimeAgoPipe } from './ticketlist/date-ago.pipe';
import { ContactService } from './contacts/contact.service';
import { NoteService } from './notes/note.service';
import { TodoService } from './todos/todo.service';
import { UserService } from './users/userService.service';
import { TasksService } from './tasks/tasks-service.service';
// New
import { MailGlobalVariable } from './mail/mail.service';
import { MailService } from './mail/mailService';
// rxjs
import { UserRxjsComponent } from './user-rxjs/user-rxjs.component';
import { UserRxjsServiceService } from './user-rxjs/user-rxjs-service.service';
import { ContactRxjsComponent } from './contact-rxjs/contact-rxjs.component';
import { ServiceContactrxjsService } from './contact-rxjs/service-contactrxjs.service';
import { ContactListRxjsComponent } from './contact-list-rxjs/contact-list-rxjs.component';
import { ServiceContactlistRxjsService } from './contact-list-rxjs/service-contactlist-rxjs.service';
import { InvoiceService } from './invoice/invoice.service';
import { AddInvoiceComponent } from './invoice/add-invoice/add-invoice.component';
import { ListInvoicesComponent } from './invoice/list-invoices/list-invoices.component';
import { ViewInvoiceComponent } from './invoice/view-invoice/view-invoice.component';
import { EditInvoiceComponent } from './invoice/edit-invoice/edit-invoice.component';
import { ListTemplateImportComponent } from './users/list-template-import/list-template-import.component';
import { ListTemplateExportComponent } from './users/list-template-export/list-template-export.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
NgbModule,
NgbModalModule,
CalendarModule.forRoot({
provide: DateAdapter,
useFactory: adapterFactory
}),
QuillModule.forRoot(),
RouterModule.forChild(AppsRoutes),
PerfectScrollbarModule,
Ng2SearchPipeModule,
DragDropModule,
FlatpickrModule.forRoot(),
HttpClientModule,
FeatherModule
],
declarations: [
ChatComponent,
TicketsComponent,
TicketdetailsComponent,
TaskboardComponent,
TodosComponent,
ContactComponent,
ContactsComponent,
FullcalendarComponent,
NotesComponent,
TimeAgoPipe,
ListUsersComponent,
EditAddUserComponent,
TasksComponent,
ContactListComponent,
MailboxComponent,
ListingComponent,
DetailComponent,
ComposeComponent,
UserRxjsComponent,
ContactRxjsComponent,
ContactListRxjsComponent,
AddInvoiceComponent,
ListInvoicesComponent,
ViewInvoiceComponent,
EditInvoiceComponent,
JobsListComponent,
JobDetailComponent,
JobApplyComponent,
ListTemplateImportComponent,
ListTemplateExportComponent
],
providers: [
ContactService,
NoteService,
TodoService,
UserService,
DatePipe,
TicketService,
DecimalPipe,
TasksService,
MailService,
MailGlobalVariable,
UserRxjsServiceService,
ServiceContactrxjsService,
ServiceContactlistRxjsService,
InvoiceService,
ServicejobService
]
})
export class AppsModule { }
import { Routes } from "@angular/router";
import { ChatComponent } from "./chat/chat.component";
import { TicketsComponent } from "./ticketlist/tickets.component";
import { TicketdetailsComponent } from "./ticketdetails/ticketdetails.component";
import { TaskboardComponent } from "./taskboard/taskboard.component";
import { FullcalendarComponent } from "./fullcalendar/fullcalendar.component";
import { TodosComponent } from "./todos/todos.component";
import { NotesComponent } from "./notes/notes.component";
import { ContactComponent } from "./contact/contact.component";
import { ContactsComponent } from "./contacts/contacts.component";
import { TasksComponent } from "./tasks/tasks.component";
import { ContactListComponent } from "./contact-list/contact-list.component";
import { MailboxComponent } from "./mail/mailbox.component";
import { DetailComponent } from "./mail/detail/detail.component";
import { ComposeComponent } from "./mail/compose/compose.component";
import { ListUsersComponent } from "./users/list-users/list-users.component";
import { UserRxjsComponent } from "./user-rxjs/user-rxjs.component";
import { ContactRxjsComponent } from "./contact-rxjs/contact-rxjs.component";
import { ContactListRxjsComponent } from "./contact-list-rxjs/contact-list-rxjs.component";
import { ListInvoicesComponent } from "./invoice/list-invoices/list-invoices.component";
import { AddInvoiceComponent } from "./invoice/add-invoice/add-invoice.component";
import { ViewInvoiceComponent } from "./invoice/view-invoice/view-invoice.component";
import { EditInvoiceComponent } from "./invoice/edit-invoice/edit-invoice.component";
import { JobsListComponent } from "./jobs/jobs-list/jobs-list.component";
import { JobDetailComponent } from "./jobs/job-detail/job-detail.component";
import { JobApplyComponent } from "./jobs/job-apply/job-apply.component";
import { ListTemplateImportComponent } from "./users/list-template-import/list-template-import.component";
import { ListTemplateExportComponent } from "./users/list-template-export/list-template-export.component";
export const AppsRoutes: Routes = [
{
path: "",
children: [
{
path: "chat",
component: ChatComponent,
data: {
title: "",
urls: [],
},
},
{
path: "mail/:type",
component: MailboxComponent,
children: [
{ path: ":id", component: DetailComponent },
{ path: "/compose", component: ComposeComponent },
],
data: {
title: "",
urls: [],
},
},
{
path: "ticket/ticketlist",
component: TicketsComponent,
data: {
title: "Ticket List",
urls: [
{ title: "Dashboard", url: "/dashboard" },
{ title: "Ticket List" },
],
},
},
{
path: "ticket/ticketdetails",
component: TicketdetailsComponent,
data: {
title: "Ticket Details",
urls: [
{ title: "Dashboard", url: "/dashboard" },
{ title: "Ticket Details" },
],
},
},
{
path: "taskboard",
component: TaskboardComponent,
data: {
title: "Taskboard",
urls: [
{ title: "Dashboard", url: "/dashboard" },
{ title: "Taskboard" },
],
},
},
{
path: "fullcalendar",
component: FullcalendarComponent,
data: {
title: "Full-Calendar",
urls: [
{ title: "Dashboard", url: "/dashboard" },
{ title: "Full-Calendar" },
],
},
},
{
path: "todo",
component: TodosComponent,
data: {
title: "",
urls: [],
},
},
{
path: "tasks",
component: TasksComponent,
data: {
title: "",
urls: [],
},
},
{
path: "contact-list",
component: ContactListComponent,
data: {
title: "",
urls: [],
},
},
{
path: "contact-list-rxjs",
component: ContactListRxjsComponent,
data: {
title: "",
urls: [],
},
},
{
path: "notes",
component: NotesComponent,
data: {
title: "",
urls: [],
},
},
{
path: "users",
component: ListUsersComponent,
data: {
title: "Users App",
urls: [
{ title: "Dashboard", url: "/dashboard" },
{ title: "Users App" },
],
},
},
{
path: "import-template",
component: ListTemplateImportComponent,
data: {
title: "Import Template",
urls: [
{ title: "Import Template" },
],
},
},
{
path: "export-template",
component: ListTemplateExportComponent,
data: {
title: "Export Template",
urls: [
{ title: "Export Template" },
],
},
},
{
path: "usersrxjs",
component: UserRxjsComponent,
data: {
title: "Users-Rxjs App",
urls: [
{ title: "Apps", url: "/dashboard" },
{ title: "Users-Rxjs App" },
],
},
},
{
path: "contact-grid",
component: ContactComponent,
data: {
title: "Contact Grid",
urls: [
{ title: "Dashboard", url: "/dashboard" },
{ title: "Contact Grid" },
],
},
},
{
path: "contact",
component: ContactsComponent,
data: {
title: "",
urls: [],
},
},
{
path: "contactrxjs",
component: ContactRxjsComponent,
data: {
title: "",
urls: [],
},
},
{
path: "invoice",
component: ListInvoicesComponent,
data: {
title: "Invoice",
urls: [],
},
},
{
path: "addinvoice",
component: AddInvoiceComponent,
data: {
title: "Add Invoice",
urls: [],
},
},
{
path: "viewinvoice/:id",
component: ViewInvoiceComponent,
data: {
title: "View Invoice",
urls: [],
},
},
{
path: "editinvoice/:id",
component: EditInvoiceComponent,
data: {
title: "",
urls: [],
},
},
{
path: "jobs",
component: JobsListComponent,
data: {
title: "Jobs",
urls: [],
},
},
{
path: "job-detail/:id",
component: JobDetailComponent,
data: {
title: "Jobs Details",
urls: [],
},
},
{
path: "apply-job",
component: JobApplyComponent,
data: {
title: "Apply Job",
urls: [],
},
},
],
},
];
<!-- Mobile toggle button -->
<a [ngClass]="(showSidebar)?'ti-close':'ti-menu'" class="btn btn-success show-left-part d-block d-md-none"
href="javascript:void(0)" (click)="mobileSidebar()"></a>
<div class="main-part">
<div class="left-part bg-white fixed-left-part" [ngClass]="{'show-panel': showSidebar}">
<div class="position-relative" style="height:100%;">
<div class="p-l-15 p-r-25 py-3 d-flex align-items-center mt-1 border-bottom">
<div>
<img src="assets/images/users/8.jpg" width="45" alt="user" class="rounded-circle">
</div>
<div class="text-dark m-b-0 m-l-15 font-18">
Bruce Banner
<p class="m-b-0 font-12">
<i class="fa fa-circle text-success font-10 m-r-5"></i>
<span>Online</span>
</p>
</div>
</div>
<ul class="mailbox list-style-none">
<li>
<div class="message-center" style="height: calc(100vh - 267px);" [perfectScrollbar]="config">
<div *ngFor="let contact of contactList">
<a class="message-item" [class.active]="activeChatUserId === contact.id" (click)="setActive(contact.id)">
<span class="user-img">
<img src={{contact.imagePath}} alt="user" class="rounded-circle" width="100">
<span class="profile-status online pull-right"></span>
</span>
<div class="mail-contnet">
<h5 class="message-title">{{contact.name}}</h5>
<span class="mail-desc">{{contact.signature}}</span>
<p class="time text-uppercase">{{contact.time}}</p>
</div>
</a>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="right-part">
<div class="card mb-0">
<div class="p-l-15 p-r-25 py-3 d-flex align-items-center border-bottom bg-info">
<div class="mr-3">
<img [src]="[activeChatUserImg]" alt="user" class="rounded-circle" width="50" />
</div>
<div>
<h5 class="text-white mb-0">{{ activeChatUser }}</h5>
<p class="mb-0 text-white">{{ activeChatUserStatus }}</p>
</div>
</div>
<div class="card-body py-0 pr-0">
<div class="chat-box p-r-15" #scrollMe [scrollTop]="scrollMe.scrollHeight"
style="height:calc(100vh - 350px); overflow-y: auto;">
<!--chat Row -->
<ul class="chat-list">
<li class="chat-item" [ngClass]="[chat.chatClass]" *ngFor="let chat of savedMessages">
<div class="chat-img">
<img [src]="[chat.imagePath]" alt="avatar" />
</div>
<div class="chat-content" *ngFor="let message of chat.messages">
<div class="box bg-light-info">
{{ message }}
</div>
</div>
<div class="chat-time text-lowercase" *ngIf="chat.time !='' ">{{chat.time}}</div>
</li>
<li class="chat-item odd type-msg" *ngIf="messages.length > 0">
<div class="chat-img" data-toggle="tooltip" data-placement="right" title="" data-original-title="">
<img src="assets/images/users/8.jpg" alt="user-images" />
</div>
<div class="chat-messages">
<div class="chat-content" *ngFor="let message of messages">
<div class="box bg-light-info">{{ message }}</div>
</div>
</div>
<div class="chat-time">{{ now | date: 'hh.mm a' }}</div>
</li>
</ul>
</div>
</div>
<div class="card-body border-top">
<form class="chat-app-input row">
<div class="col-9">
<input type="text" class="form-control border-0" id="iconLeft4" placeholder="Type your message and enter"
(keydown.enter)="onAddMessage();$event.preventDefault()" #messageInput>
</div>
<div class="col-3">
<button type="button" class="btn-circle btn-lg btn-cyan float-right text-white border-0"
(click)="onAddMessage()">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
import { Component, ViewChild, ElementRef, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Chat } from './chat';
import { ContactList } from './contactList';
import { ChatMessages } from './chatMessages';
import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChatComponent implements OnInit {
public config: PerfectScrollbarConfigInterface = {};
public showSidebar = false;
public now: Date | null = null;
activeChatUserId = 1;
activeChatUser: string | null | undefined = '';
activeChatUserImg: string | null = '';
activeChatUserStatus = '';
@ViewChild('messageInput', { static: true })
messageInputRef: ElementRef | null = null;
messages = new Array();
contactList: ContactList[] | null = null;
savedMessages: Chat[] | null = null;
constructor() {
const chatMessage: ChatMessages = new ChatMessages();
this.contactList = [
{
id: 1,
imagePath: 'assets/images/users/1.jpg',
name: 'Steve Rogers',
signature: 'Hey Banner, where are you?',
time: '9:30AM',
chats: chatMessage.chat1,
},
{
id: 2,
imagePath: 'assets/images/users/2.jpg',
name: 'Ram',
signature: 'ram ram ram .....',
time: '10:30AM',
chats: chatMessage.chat2,
},
{
id: 3,
imagePath: 'assets/images/users/3.jpg',
name: 'Shyam',
signature: 'shyam shyam .....',
time: '11:30AM',
chats: chatMessage.chat3,
},
{
id: 4,
imagePath: 'assets/images/users/4.jpg',
name: 'Mark',
signature: 'mark mark ......',
time: '8:30AM',
chats: chatMessage.chat4,
},
{
id: 5,
imagePath: 'assets/images/users/5.jpg',
name: 'Robin',
signature: 'robin robin ......',
time: '6:30AM',
chats: chatMessage.chat5,
}
];
// tslint:disable-next-line:no-non-null-assertion
this.activeChatUser = this.contactList!.find(x => x.id === 1)?.name;
// tslint:disable-next-line:no-non-null-assertion
this.activeChatUserImg = this.contactList!.find(x => x.id === 1)!.imagePath;
// tslint:disable-next-line:no-non-null-assertion
this.savedMessages = this.contactList!.find(x => x.id === 1)!.chats;
this.activeChatUserStatus = 'Online';
}
ngOnInit() {
}
// chat user list click event function
setActive(chatId: number) {
this.savedMessages = new Array();
this.messages = [];
if (this.contactList !== null) {
for (let i = 0; i < this.contactList.length; i++) {
if (this.contactList[i].id === chatId) {
this.activeChatUserId = this.contactList[i].id;
this.activeChatUser = this.contactList[i].name;
this.activeChatUserImg = this.contactList[i].imagePath;
this.savedMessages = this.contactList[i].chats;
this.activeChatUserStatus = 'Online';
}
}
}
}
onAddMessage() {
if (this.messageInputRef?.nativeElement.value !== '') {
this.messages.push(this.messageInputRef?.nativeElement.value);
}
if (this.messageInputRef !== null) {
this.messageInputRef.nativeElement.value = '';
this.messageInputRef.nativeElement.focus();
}
this.now = new Date();
}
mobileSidebar() {
this.showSidebar = !this.showSidebar;
}
}
export class Chat {
public chatClass: string;
public imagePath: string;
public time: string;
public messages: string[];
constructor(
chatClass: string,
imagePath: string,
time: string,
messages: string[]
) {
this.chatClass = chatClass;
this.imagePath = imagePath;
this.time = time;
this.messages = messages;
}
}
import { Chat } from './chat';
export class ChatMessages {
constructor() {
}
public chat1: Chat[] = [
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.30 am',
[
'Hi, How are you ?'
],
),
new Chat(
'even',
'assets/images/users/1.jpg',
'9.30 am',
[
'Hey Bruce, I am Fine'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.31 am',
[
'What are you doing nowadays ?'
],
),
new Chat(
'even',
'assets/images/users/1.jpg',
'9.31 am',
[
'Nothing Much.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.32 am',
[
'yes'
],
),
new Chat(
'even',
'assets/images/users/1.jpg',
'9.32 am',
[
'Do you have interest in IOS ?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.33 am',
[
'Yes, not more.'
],
)
];
public chat2: Chat[] = [new Chat(
'odd',
'assets/images/users/6.jpg',
'9.32 am',
[
'Hi ram ..'
],
),
new Chat(
'even',
'assets/images/users/2.jpg',
'9.32 am',
[
'Hi, Bruce'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.32 am',
[
'Have a knowledge about Cordova ram ..?'
],
),
new Chat(
'even',
'assets/images/users/2.jpg',
'9.34 am',
[
'Yes, You also have interest in that ?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.34 am',
[
'Yeah, I have also develop a mobile app on that ram ..'
],
),
new Chat(
'even',
'assets/images/users/2.jpg',
'9.34 am',
[
'Do you upload that on play store ?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.34 am',
[
'Nope ram ..'
],
),
new Chat(
'even',
'assets/images/users/2.jpg',
'9.35 am',
[
'Then Upload it, you will get money.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.35 am',
[
'Okay ram ...'
],
)
];
public chat3: Chat[] = [
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.37 am',
[
'Hey, How are you ?'
],
),
new Chat(
'even',
'assets/images/users/3.jpg',
'9.37 am',
[
'Hi, I am fine.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.37 am',
[
'okay'
],
),
new Chat(
'even',
'assets/images/users/3.jpg',
'9.37 am',
[
'Lets go for tea.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.39 am',
[
'Yeah, Sure'
],
),
new Chat(
'even',
'assets/images/users/3.jpg',
'9.39 am',
[
'What about time?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.39 am',
[
'I will ask you after'
],
),
new Chat(
'even',
'assets/images/users/3.jpg',
'9.39 am',
[
'Okay, let me know. Once you decide.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.41 am',
[
'Yeah'
],
),
new Chat(
'even',
'assets/images/users/3.jpg',
'9.41 am',
[
'Bye'
],
)
];
public chat4: Chat[] = [
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.21 am',
[
'Hi, How are you ?'
],
),
new Chat(
'even',
'assets/images/users/4.jpg',
'9.21 am',
[
'Hey Bruce, I am Fine'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.21 am',
[
'What are you doing nowadays ?'
],
),
new Chat(
'even',
'assets/images/users/4.jpg',
'9.21 am',
[
'Nothing Much.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.21 am',
[
'yes'
],
),
new Chat(
'even',
'assets/images/users/4.jpg',
'9.22 am',
[
'Do you have interest in IOS ?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.23 am',
[
'Yes, not more.'
],
),
new Chat(
'even',
'assets/images/users/4.jpg',
'9.24 am',
[
'Okay.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.24 am',
[
'I have join Android Classes.'
],
),
new Chat(
'even',
'assets/images/users/4.jpg',
'9.24 am',
[
'Okay, Great.'
],
)
];
public chat5: Chat[] = [
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.14 am',
[
'Hi'
],
),
new Chat(
'even',
'assets/images/users/5.jpg',
'9.14 am',
[
'Hi, Bruce'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.14 am',
[
'Have a knowledge about Cordova ?'
],
),
new Chat(
'even',
'assets/images/users/5.jpg',
'9.15 am',
[
'Yes, You also have interest in that ?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.15 am',
[
'Yeah, I have also develop a mobile app on that'
],
),
new Chat(
'even',
'assets/images/users/5.jpg',
'9.15 am',
[
'Do you upload that on play store ?'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.16 am',
[
'Nope'
],
),
new Chat(
'even',
'assets/images/users/5.jpg',
'9.16 am',
[
'Then Upload it, you will get money.'
],
),
new Chat(
'odd',
'assets/images/users/6.jpg',
'9.16 am',
[
'Okay.'
],
)
];
}
import { Chat } from './chat';
export class ContactList {
public id = 0;
public imagePath: string | null = null;
public name: string | null = null;
public signature: string | null = null;
public time: string | null = null;
public chats: Chat[] | null = null;
}
import { ContactLists } from './contact-list';
export const ContactList: ContactLists[] = [
{
Id: 1,
Imagepath: 'assets/images/users/2.jpg',
Name: 'Emma Adams',
Tags: 'Friend',
Jobtitle: 'Web Developer',
Company: 'Wrappixel',
Email: 'adams@mail.com',
Phonenumber: 1548462031,
Address: 'Boston, USA',
DOB: new Date,
Description: 'Felis bibendum ut tristique et egestas quis. In cursus turpis massa tincidunt dui ut.'
},
{
Id: 2,
Imagepath: 'assets/images/users/3.jpg',
Name: 'Olivia Allen',
Tags: 'Family',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'allen@mail.com',
Phonenumber: 9478021640,
Address: 'Sydney, Australia',
DOB: new Date,
Description: 'Est ante in nibh mauris cursus mattis molestie a iaculis.'
},
{
Id: 3,
Imagepath: 'assets/images/users/4.jpg',
Name: 'Emily Atkinson',
Tags: 'Friend',
Jobtitle: 'UX/UI Designer',
Company: 'Google',
Email: 'atkinson@mail.com',
Phonenumber: 6302154203,
Address: 'Edinburgh, UK',
DOB: new Date,
Description: 'Orci nulla pellentesque dignissim enim.'
},
{
Id: 4,
Imagepath: 'assets/images/users/5.jpg',
Name: 'Isabella Anderson',
Tags: 'Friend',
Jobtitle: 'UX/UI Designer',
Company: 'Tesala',
Email: 'anderson@mail.com',
Phonenumber: 1503201502,
Address: 'Miami, USA',
DOB: new Date,
Description: 'Gravida cum sociis natoque penatibus et magnis dis parturient.'
},
{
Id: 5,
Imagepath: 'assets/images/users/6.jpg',
Name: 'Amelia Armstrong',
Tags: 'Office',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'armstrong@mail.com',
Phonenumber: 8124502316,
Address: 'Tokyo, Japan',
DOB: new Date,
Description: 'Sit amet luctus venenatis lectus magna fringilla urna porttitor.'
},
{
Id: 6,
Imagepath: 'assets/images/users/7.jpg',
Name: 'Sofia Bailey',
Tags: 'Family',
Jobtitle: 'Theme Designer',
Company: 'Google',
Email: 'bailey@mail.com',
Phonenumber: 7080642130,
Address: 'New York, USA',
DOB: new Date,
Description: 'Sapien et ligula ullamcorper malesuada proin libero nunc.'
},
{
Id: 7,
Imagepath: 'assets/images/users/8.jpg',
Name: 'Victoria Sharma',
Tags: 'Friend',
Jobtitle: 'Project Manager',
Company: 'Wrappixel',
Email: 'sharma@mail.com',
Phonenumber: 9040263102,
Address: 'Miami, USA',
DOB: new Date,
Description: 'Id venenatis a condimentum vitae sapien pellentesque habitant morbi.'
},
{
Id: 8,
Imagepath: 'assets/images/users/agent.jpg',
Name: 'Olivia Allen',
Tags: 'Friend',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'allen@mail.com',
Phonenumber: 7800245169,
Address: 'Sydney, Australia',
DOB: new Date,
Description: 'Elit at imperdiet dui accumsan sit amet nulla facilisi morbi. Porta lorem mollis aliquam ut porttitor leo a diam.'
},
{
Id: 9,
Imagepath: 'assets/images/users/agent2.jpg',
Name: 'Emily Atkinson',
Tags: 'Office',
Jobtitle: 'UX/UI Designer',
Company: 'Google',
Email: 'atkinson@mail.com',
Phonenumber: 9874560213,
Address: 'Edinburgh, UK',
DOB: new Date,
Description: 'Vivamus arcu felis bibendum ut tristique.'
},
{
Id: 10,
Imagepath: 'assets/images/users/d2.jpg',
Name: 'Emma Adams',
Tags: 'Office',
Jobtitle: 'Web Developer',
Company: 'Wrappixel',
Email: 'adams@mail.com',
Phonenumber: 4500231620,
Address: 'Boston, USA',
DOB: new Date,
Description: 'Habitasse platea dictumst vestibulum rhoncus.'
},
{
Id: 11,
Imagepath: 'assets/images/users/3.jpg',
Name: 'Olivia Allen',
Tags: 'Friend',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'allen@mail.com',
Phonenumber: 9748020130,
Address: 'Sydney, Australia',
DOB: new Date,
Description: 'Aliquet porttitor lacus luctus accumsan tortor posuere.'
},
{
Id: 12,
Imagepath: 'assets/images/users/4.jpg',
Name: 'Emily Atkinson',
Tags: 'Friend',
Jobtitle: 'UX/UI Designer',
Company: 'Google',
Email: 'atkinson@mail.com',
Phonenumber: 8200154212,
Address: 'Edinburgh, UK',
DOB: new Date,
Description: 'Elit at imperdiet dui accumsan sit amet nulla.'
},
];
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ContactListRxjsComponent } from './contact-list-rxjs.component';
describe('ContactListRxjsComponent', () => {
let component: ContactListRxjsComponent;
let fixture: ComponentFixture<ContactListRxjsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactListRxjsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContactListRxjsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});
import { Component, OnInit } from '@angular/core';
import { ContactLists } from './contact-list';
import { ServiceContactlistRxjsService } from './service-contactlist-rxjs.service';
@Component({
selector: 'app-contact-list-rxjs',
templateUrl: './contact-list-rxjs.component.html',
styleUrls: ['./contact-list-rxjs.component.css']
})
export class ContactListRxjsComponent implements OnInit {
contacts: ContactLists[] = [];
contactFilter: ContactLists[] | null = null;
selectedContact: ContactLists | null = null;
selectedContactCopy: ContactLists | null | any = null;
editable = false;
page = 1;
pageSize = 5;
collectionSize = 0;
_searchTerm = '';
// image.......................................
public imagePath: string | null = null;
imgURL: string | null = null;
public message = '';
constructor(public contactListservice: ServiceContactlistRxjsService) {
this.contactListservice.getContactList().subscribe((data) => {
this.contacts.push(data);
})
}
ngOnInit() {
this.contactFilter = this.contacts;
this.collectionSize = this.contactFilter.length;
this.selectedContact = null;
}
// search...
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this._searchTerm = val;
this.contactFilter = this.filter(val);
}
filter(v: string) {
return this.contacts.filter(x => x.Name.toLowerCase().indexOf(v.toLowerCase()) !== -1);
}
// table row clicked...
tableRowClicked(contact: ContactLists) {
this.selectedContact = contact;
(document.getElementById('rightMenu') as HTMLFormElement).style.width = '300px';
this.editContact();
}
viewClicked(contact: ContactLists) {
this.selectedContact = contact;
(document.getElementById('rightMenu') as HTMLFormElement).style.width = '300px';
}
// right menu closed...
closeRightMenu() {
this.editable = false;
this.selectedContact = null;
this.selectedContactCopy = null;
(document.getElementById('rightMenu') as HTMLFormElement).style.width = '0';
}
editContact() {
this.selectedContactCopy = Object.assign({}, this.selectedContact);
this.editable = true;
}
// cancel clicked on right menu...
cancelClick() {
this.selectedContact = null;
this.selectedContactCopy = null;
this.closeRightMenu();
}
// edit contact-list...
saveClick(id: number) {
if (this.contactFilter) {
const c: ContactLists | undefined = this.contactFilter.find(con => con.Id === id);
if (c !== undefined && this.selectedContactCopy) {
c.Imagepath = this.selectedContactCopy.Imagepath;
c.Name = this.selectedContactCopy.Name;
c.Tags = this.selectedContactCopy.Tags;
c.Jobtitle = this.selectedContactCopy.Jobtitle;
c.Company = this.selectedContactCopy.Company;
c.Email = this.selectedContactCopy.Email;
c.Phonenumber = this.selectedContactCopy.Phonenumber;
c.Address = this.selectedContactCopy.Address;
c.DOB = this.selectedContactCopy.DOB;
c.Description = this.selectedContactCopy.Description;
this.contactListservice.updateContactList(id, c);
this.closeRightMenu();
}
}
}
// delete click...
deleteClick(id: number) {
if (this.contactFilter) {
this.contactListservice.deleteContactList(id);
this.contactFilter = this.contactFilter.filter(user => user.Id !== id);
}
this.collectionSize--;
this.selectedContact = null;
this.closeRightMenu();
}
// add contact...
addContact() {
const con: ContactLists = new ContactLists();
if (this.contactFilter) {
const n = Math.max.apply(Math,
this.contactFilter.map(function (o) { return o.Id; })) + 1;
con.Id = n;
}
con.Imagepath = '/assets/images/users/1.jpg';
con.Name = 'New Contact';
con.Tags = 'Test';
con.Jobtitle = 'Web Designer';
con.Company = 'Wrappixel';
con.Email = 'newcontact@gmail.com';
con.Phonenumber = 9405123015;
con.Address = 'Bhavnagar, India';
con.DOB = new Date;
con.Description = 'Add a Description';
this.contactListservice.addContactList(con);
this.contactFilter?.splice(0, 0, con);
this.collectionSize++;
this.tableRowClicked(con);
this.editContact();
}
preview(files: any) {
if (files.length === 0) {
return;
}
const mimeType = files[0].type;
if (mimeType.match(/image\/*/) == null) {
this.message = 'Only images are supported.';
return;
}
const reader = new FileReader();
this.imagePath = files;
reader.readAsDataURL(files[0]);
reader.onload = (_event) => {
this.selectedContactCopy!.Imagepath = reader.result;
};
}
}
export class ContactLists {
Id = 0;
Imagepath: string | null | undefined = '';
Name = '';
Tags = '';
Jobtitle = '';
Company = '';
Email = '';
Phonenumber = 0;
Address = '';
DOB: Date | null = null;
Description = '';
}
import { TestBed } from '@angular/core/testing';
import { ServiceContactlistRxjsService } from './service-contactlist-rxjs.service';
describe('ServiceContactlistRxjsService', () => {
let service: ServiceContactlistRxjsService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ServiceContactlistRxjsService);
});
// it('should be created', () => {
// expect(service).toBeTruthy();
// });
});
import { Injectable } from '@angular/core';
import { from, Observable } from 'rxjs';
import { ContactLists } from './contact-list';
import { ContactList } from './contact-list-data';
@Injectable({
providedIn: 'root'
})
export class ServiceContactlistRxjsService {
constructor() { }
private contactList: ContactLists[] = ContactList;
// getContactList(): Observable<ContactLists> {
// You can also fetch data from Api using HttpClient.
// return this.http.get(url..)
// }
getContactList(): Observable<ContactLists> {
return from(this.contactList);
}
deleteContactList(id: number): void {
this.contactList = this.contactList.filter(cl => cl.Id !== id);
}
addContactList(cl: ContactLists): void {
this.contactList?.push(cl);
}
updateContactList(index: number, cl: ContactLists): void {
this.contactList[index] = cl;
}
}
import { ContactLists } from './contact-list';
export const ContactList: ContactLists[] = [
{
Id: 1,
Imagepath: 'assets/images/users/2.jpg',
Name: 'Emma Adams',
Tags: 'Friend',
Jobtitle: 'Web Developer',
Company: 'Wrappixel',
Email: 'adams@mail.com',
Phonenumber: 1548462031,
Address: 'Boston, USA',
DOB: new Date,
Description: 'Felis bibendum ut tristique et egestas quis. In cursus turpis massa tincidunt dui ut.'
},
{
Id: 2,
Imagepath: 'assets/images/users/3.jpg',
Name: 'Olivia Allen',
Tags: 'Family',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'allen@mail.com',
Phonenumber: 9478021640,
Address: 'Sydney, Australia',
DOB: new Date,
Description: 'Est ante in nibh mauris cursus mattis molestie a iaculis.'
},
{
Id: 3,
Imagepath: 'assets/images/users/4.jpg',
Name: 'Emily Atkinson',
Tags: 'Friend',
Jobtitle: 'UX/UI Designer',
Company: 'Google',
Email: 'atkinson@mail.com',
Phonenumber: 6302154203,
Address: 'Edinburgh, UK',
DOB: new Date,
Description: 'Orci nulla pellentesque dignissim enim.'
},
{
Id: 4,
Imagepath: 'assets/images/users/5.jpg',
Name: 'Isabella Anderson',
Tags: 'Friend',
Jobtitle: 'UX/UI Designer',
Company: 'Tesala',
Email: 'anderson@mail.com',
Phonenumber: 1503201502,
Address: 'Miami, USA',
DOB: new Date,
Description: 'Gravida cum sociis natoque penatibus et magnis dis parturient.'
},
{
Id: 5,
Imagepath: 'assets/images/users/6.jpg',
Name: 'Amelia Armstrong',
Tags: 'Office',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'armstrong@mail.com',
Phonenumber: 8124502316,
Address: 'Tokyo, Japan',
DOB: new Date,
Description: 'Sit amet luctus venenatis lectus magna fringilla urna porttitor.'
},
{
Id: 6,
Imagepath: 'assets/images/users/7.jpg',
Name: 'Sofia Bailey',
Tags: 'Family',
Jobtitle: 'Theme Designer',
Company: 'Google',
Email: 'bailey@mail.com',
Phonenumber: 7080642130,
Address: 'New York, USA',
DOB: new Date,
Description: 'Sapien et ligula ullamcorper malesuada proin libero nunc.'
},
{
Id: 7,
Imagepath: 'assets/images/users/8.jpg',
Name: 'Victoria Sharma',
Tags: 'Friend',
Jobtitle: 'Project Manager',
Company: 'Wrappixel',
Email: 'sharma@mail.com',
Phonenumber: 9040263102,
Address: 'Miami, USA',
DOB: new Date,
Description: 'Id venenatis a condimentum vitae sapien pellentesque habitant morbi.'
},
{
Id: 8,
Imagepath: 'assets/images/users/agent.jpg',
Name: 'Olivia Allen',
Tags: 'Friend',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'allen@mail.com',
Phonenumber: 7800245169,
Address: 'Sydney, Australia',
DOB: new Date,
Description: 'Elit at imperdiet dui accumsan sit amet nulla facilisi morbi. Porta lorem mollis aliquam ut porttitor leo a diam.'
},
{
Id: 9,
Imagepath: 'assets/images/users/agent2.jpg',
Name: 'Emily Atkinson',
Tags: 'Office',
Jobtitle: 'UX/UI Designer',
Company: 'Google',
Email: 'atkinson@mail.com',
Phonenumber: 9874560213,
Address: 'Edinburgh, UK',
DOB: new Date,
Description: 'Vivamus arcu felis bibendum ut tristique.'
},
{
Id: 10,
Imagepath: 'assets/images/users/d2.jpg',
Name: 'Emma Adams',
Tags: 'Office',
Jobtitle: 'Web Developer',
Company: 'Wrappixel',
Email: 'adams@mail.com',
Phonenumber: 4500231620,
Address: 'Boston, USA',
DOB: new Date,
Description: 'Habitasse platea dictumst vestibulum rhoncus.'
},
{
Id: 11,
Imagepath: 'assets/images/users/3.jpg',
Name: 'Olivia Allen',
Tags: 'Friend',
Jobtitle: 'Ethical Hacker',
Company: 'Infosys',
Email: 'allen@mail.com',
Phonenumber: 9748020130,
Address: 'Sydney, Australia',
DOB: new Date,
Description: 'Aliquet porttitor lacus luctus accumsan tortor posuere.'
},
{
Id: 12,
Imagepath: 'assets/images/users/4.jpg',
Name: 'Emily Atkinson',
Tags: 'Friend',
Jobtitle: 'UX/UI Designer',
Company: 'Google',
Email: 'atkinson@mail.com',
Phonenumber: 8200154212,
Address: 'Edinburgh, UK',
DOB: new Date,
Description: 'Elit at imperdiet dui accumsan sit amet nulla.'
},
];
.image {
display: block;
margin-left: auto;
margin-right: auto;
}
.cursor-pointer {
cursor: pointer;
}
import { Component, OnInit } from '@angular/core';
import { ContactList } from './contact-list-data';
import { ContactLists } from './contact-list';
import { MailGlobalVariable } from '../mail/mail.service';
@Component({
selector: 'app-contact-list',
templateUrl: './contact-list.component.html',
styleUrls: ['./contact-list.component.css']
})
export class ContactListComponent implements OnInit {
contacts: ContactLists[] = ContactList;
contactFilter: ContactLists[] | null = null;
selectedContact: ContactLists | null = null;
selectedContactCopy: ContactLists | null | any = null;
editable = false;
page = 1;
pageSize = 5;
collectionSize = 0;
_searchTerm = '';
// image.......................................
public imagePath: string | null = null;
imgURL: string | null = null;
public message = '';
constructor(public ms: MailGlobalVariable) {
this.ms.selectedMail = null;
}
ngOnInit() {
this.contactFilter = this.contacts;
this.collectionSize = this.contactFilter.length;
this.selectedContact = null;
}
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this._searchTerm = val;
this.contactFilter = this.filter(val);
}
filter(v: string) {
return this.contacts.filter(x => x.Name.toLowerCase().indexOf(v.toLowerCase()) !== -1);
}
tableRowClicked(contact: ContactLists) {
this.selectedContact = contact;
(document.getElementById('rightMenu') as HTMLFormElement).style.width = '300px';
this.editContact();
}
viewClicked(contact: ContactLists) {
this.selectedContact = contact;
(document.getElementById('rightMenu') as HTMLFormElement).style.width = '300px';
}
closeRightMenu() {
this.editable = false;
this.selectedContact = null;
this.selectedContactCopy = null;
(document.getElementById('rightMenu') as HTMLFormElement).style.width = '0';
}
editContact() {
this.selectedContactCopy = Object.assign({}, this.selectedContact);
this.editable = true;
}
cancelClick() {
this.selectedContact = null;
this.selectedContactCopy = null;
this.closeRightMenu();
}
saveClick(id: number) {
if (this.contactFilter) {
const c: ContactLists | undefined = this.contactFilter.find(con => con.Id === id);
if (c !== undefined && this.selectedContactCopy) {
c.Imagepath = this.selectedContactCopy.Imagepath;
c.Name = this.selectedContactCopy.Name;
c.Tags = this.selectedContactCopy.Tags;
c.Jobtitle = this.selectedContactCopy.Jobtitle;
c.Company = this.selectedContactCopy.Company;
c.Email = this.selectedContactCopy.Email;
c.Phonenumber = this.selectedContactCopy.Phonenumber;
c.Address = this.selectedContactCopy.Address;
c.DOB = this.selectedContactCopy.DOB;
c.Description = this.selectedContactCopy.Description;
this.closeRightMenu();
}
}
}
deleteClick(id: number) {
if (this.contactFilter) {
this.contactFilter = this.contactFilter.filter(user => user.Id !== id);
}
this.collectionSize--;
// id = id - 1;
// this.contacts.splice(id, 1);
this.selectedContact = null;
this.closeRightMenu();
}
addContact() {
const con: ContactLists = new ContactLists();
if (this.contactFilter) {
const n = Math.max.apply(Math,
this.contactFilter.map(function (o) { return o.Id; })) + 1;
con.Id = n;
}
con.Imagepath = '/assets/images/users/1.jpg';
con.Name = 'New Contact';
con.Tags = 'Test';
con.Jobtitle = 'Job Title';
con.Company = 'Company';
con.Email = 'newcontact@gmail.com';
con.Phonenumber = 1111111111;
con.Address = 'City, Country';
con.DOB = new Date;
con.Description = 'Add a Description';
this.contactFilter?.splice(0, 0, con);
this.collectionSize++;
this.tableRowClicked(con);
this.editContact();
}
preview(files: any) {
if (files.length === 0) {
return;
}
const mimeType = files[0].type;
if (mimeType.match(/image\/*/) == null) {
this.message = 'Only images are supported.';
return;
}
const reader = new FileReader();
this.imagePath = files;
reader.readAsDataURL(files[0]);
reader.onload = (_event) => {
this.selectedContactCopy!.Imagepath = reader.result;
};
}
}
export class ContactLists {
Id = 0;
Imagepath: string | null | undefined = '';
Name = '';
Tags = '';
Jobtitle = '';
Company = '';
Email = '';
Phonenumber = 0;
Address = '';
DOB: Date | null = null;
Description = '';
}
import { Contact } from './contact';
export const contacts: Contact[] = [
{
id:1,
firstName: 'Raj',
lastName: 'Dev',
mobile: '979797992',
home: 'jodhpur',
company: ' F creation',
work: 'AD',
notes: ' i qb inujjbw.',
imagePath: 'assets/images/users/5.jpg'
},
{
id:2,
firstName: 'Mark',
lastName: 'Smith',
mobile: '989797772',
home: 'Rajasthan',
company: ' F creation',
work: 'Designer',
notes: ' noyes kns nal sjj s slhjal.',
imagePath: 'assets/images/users/2.jpg'
},
{
id:3,
firstName: 'Jony',
lastName: 'Deep',
mobile: '9234567563',
home: 'LA',
company: ' F creation',
work: 'Admin',
notes: ' admin : baun ja ayu gsiko iaij sikioa...',
imagePath: 'assets/images/users/3.jpg'
},
{
id:4,
firstName: 'Leonardo',
lastName: 'Caprio',
mobile: '7837937777',
home: 'NJ',
company: ' F creation',
work: 'ADMIN',
notes: 'Leo nah ujhakj jjj akkak asdkfga an a .',
imagePath: 'assets/images/users/4.jpg'
}
];
<!-- Mobile toggle button -->
<a [ngClass]="(showSidebar)?'ti-close':'ti-menu'" class="btn btn-success show-left-part d-block d-md-none"
href="javascript:void(0)" (click)="mobileSidebar()"></a>
<div class="main-part">
<!-- Left Part -->
<div class="left-part bg-white fixed-left-part" [ngClass]="{'show-panel': showSidebar}">
<div class="position-relative">
<div class="p-l-15 p-r-25 py-3 d-flex align-items-center border-bottom">
<input type="text" class="form-control" placeholder="Search Contact" [(ngModel)]='searchTerm'>
</div>
<ul class="contact-list list-style-none">
<li class="contact-item border-bottom p-3" *ngFor='let c of filterArray' [class.active]="c === selectedContact"
(click)="onSelect(c);">
<img class="rounded-circle" [src]='c.imagePath' height="40" width="40" />
<span class="ml-3 font-medium">{{c.firstName}}&nbsp;{{c.lastName}}</span>
</li>
</ul>
</div>
</div>
<!-- End Left Part -->
<!-- Right Part -->
<div class="right-part bg-white">
<div class="card">
<div class="">
<button type="button" id="btnAddContact" class="btn btn-primary" (click)='addContact()'>Add New
Contact</button>
<!-- Contact detail -->
<div *ngIf="selectedContact">
<div class="px-3 py-3 d-flex align-items-center border-bottom">
<a href="javascript: void(0);" (click)='editContact()' class="btn btn-success mr-2">
{{editSave}}
</a>
<a href="javascript: void(0);" class="btn btn-danger" (click)='deleteContact(selectedContact)'>
Delete
</a>
</div>
<div class="px-3">
<div class="row" *ngIf="show" (click)="editContact()">
<div class="col-md-2 text-center col-xl-1"><img class="rounded-circle mt-4"
[src]='selectedContact.imagePath' height="100" width="100"></div>
<div class="col-md-8">
<table class="table mt-3 table-lg table-borderless v-middle">
<tbody>
<tr>
<td class="font-bold detail-title">Name</td>
<td class="pl-2">{{selectedContact.firstName}}&nbsp;{{selectedContact.lastName}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Company</td>
<td class="pl-2">{{selectedContact.company}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Work</td>
<td class="pl-2">{{selectedContact.work}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Phone</td>
<td class="pl-2">{{selectedContact.mobile}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Address</td>
<td class="pl-2">{{selectedContact.home}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Note</td>
<td class="pl-2">{{selectedContact.notes}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mt-4 row" *ngIf="!show">
<div class="col-md-2 text-center col-xl-1"><img class="rounded-circle mt-4 flex-shrink-0"
[src]='selectedContact.imagePath' height="100" width="100"></div>
<div class="col-md-8">
<table class="ml-4 table table-borderless v-middle">
<tbody>
<tr>
<td class="font-bold detail-title">Name</td>
<td class="d-flex">
<input type="text" [(ngModel)]="selectedContact.firstName" class="form-control">
<input type="text" [(ngModel)]="selectedContact.lastName" class="form-control ml-2"></td>
</tr>
<tr>
<td class="font-bold detail-title">Company</td>
<td><input type="text" [(ngModel)]="selectedContact.company" class="form-control"></td>
</tr>
<tr>
<td class="font-bold detail-title">Work</td>
<td><input type="text" [(ngModel)]="selectedContact.work" class="form-control"></td>
</tr>
<tr>
<td class="font-bold detail-title">Phone</td>
<td><input type="text" [(ngModel)]="selectedContact.mobile" class="form-control" maxlength="10">
</td>
</tr>
<tr>
<td class="font-bold detail-title">Address</td>
<td><input type="text" [(ngModel)]="selectedContact.home" class="form-control"></td>
</tr>
<tr>
<td class="font-bold detail-title">Note</td>
<td><textarea [(ngModel)]="selectedContact.notes" class="form-control"></textarea></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- End Contact detail -->
</div>
</div>
</div>
<!-- End Right Part -->
</div>
.detail-title {
width: 80px;
position: relative;
&:after {
content: ":";
position: absolute;
right: 0px;
}
}
.contact-list {
.contact-item {
&:hover {
cursor: pointer;
}
&.active {
background-color: #e9ecef;
}
}
}
#btnAddContact {
position: absolute;
right: 15px;
top: 15px;
}
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ContactRxjsComponent } from './contact-rxjs.component';
describe('ContactRxjsComponent', () => {
let component: ContactRxjsComponent;
let fixture: ComponentFixture<ContactRxjsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactRxjsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContactRxjsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});
import { Component, OnInit } from '@angular/core';
import { Contact } from './contact';
import { ServiceContactrxjsService } from './service-contactrxjs.service';
@Component({
selector: 'app-contact-rxjs',
templateUrl: './contact-rxjs.component.html',
styleUrls: ['./contact-rxjs.component.scss']
})
export class ContactRxjsComponent implements OnInit {
public showSidebar = false;
contacts: Contact[] = [];
filterArray: Contact[] = [];
selectedContact: Contact | null = null;
show = true;
editSave = 'Edit';
constructor(public contactService: ServiceContactrxjsService) {
this.contactService.getContacts().subscribe((data) => {
this.contacts.push(data);
});
}
ngOnInit() {
this.filterArray = this.contacts;
if (this.contacts.length > 0) {
this.onSelect(this.contacts[0]);
}
}
mobileSidebar() {
this.showSidebar = !this.showSidebar;
}
// search...
_searchTerm = '';
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this._searchTerm = val;
this.filterArray = this.filter(val);
}
filter(v: string) {
return this.contacts.filter(x => x.firstName.toLowerCase().
indexOf(v.toLowerCase()) !== -1 || x.lastName.toLowerCase().indexOf(v.toLowerCase()) !== -1);
}
//on click contact...
onSelect(contact: Contact) {
this.selectedContact = contact;
}
// edit contact...
editContact() {
if (this.editSave === 'Save') {
this.show = true;
this.editSave = 'Edit';
} else {
this.show = false;
this.editSave = 'Save';
}
}
// add contact...
addContact() {
let c: Contact = new Contact()
c.id = Math.max.apply(Math, this.filterArray.map(function (o) { return o.id; })) + 1;
c.firstName = 'First Name';
c.lastName = 'Last Name';
c.mobile = '';
c.home = '';
c.company = '';
c.work = '';
c.notes = '';
c.imagePath = 'assets/images/users/1.jpg';
this.contactService.addContact(c);
this.filterArray.splice(0,0,c);
this.selectedContact = this.filterArray[0];
this.editContact();
}
// delete contact...
deleteContact(contact: Contact) {
this.contactService.deleteContact(contact);
this.filterArray = this.filterArray.filter(con => con.firstName !== contact.firstName && con.lastName !== contact.lastName);
this.selectedContact = null;
}
}
export class Contact {
id=0;
firstName = '';
lastName = '';
mobile = '';
home = '';
company = '';
work = '';
notes = '';
imagePath = '';
}
import { TestBed } from '@angular/core/testing';
import { ServiceContactrxjsService } from './service-contactrxjs.service';
describe('ServiceContactrxjsService', () => {
let service: ServiceContactrxjsService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ServiceContactrxjsService);
});
// it('should be created', () => {
// expect(service).toBeTruthy();
// });
});
import { Injectable } from '@angular/core';
import { from, Observable } from 'rxjs';
import { Contact } from './contact';
import { contacts } from './contact-data';
@Injectable({
providedIn: 'root'
})
export class ServiceContactrxjsService {
constructor() { }
private contacts: Contact[] = contacts;
// getContacts(): Observable<Contact> {
// You can also fetch data from Api using HttpClient.
// return this.http.get(url..)
// }
getContacts(): Observable<Contact> {
return from(this.contacts)
}
deleteContact(contact: Contact): void {
this.contacts = this.contacts.filter(Contact =>
Contact.firstName !== contact.firstName && Contact.lastName !== contact.lastName);
}
addContact(con: Contact): void {
this.contacts?.push(con);
}
}
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-6 col-lg-3 col-xl-2">
<input type="text" class="form-control form-control-lg" type="text" name="search" [(ngModel)]="searchText"
autocomplete="off" placeholder="Search here...">
</div>
<div class="col-md-6 col-lg-9 col-xl-10 text-md-right mt-4 mt-md-0">
<button class="btn btn-lg btn-cyan text-white" (click)="open(addContactModal)">
<i class="fa fa-plus-square mr-2"></i>Add Contact</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row justify-content-center" *ngIf='contact && contact.length'>
<div class="col-md-4" *ngFor="let c of contact | filter:searchText">
<div class="card">
<div class="card-body text-center">
<img src="{{ c.img }}" class="rounded-circle border p-1" width="100">
<h4 class="card-title mt-3 mb-0">{{ c.name }}</h4>
<small class="text-muted">{{ c.post }}</small>
<div class="mt-3">
<button class="btn btn-info">Chat</button>
<button class="btn btn-light">Follow</button>
</div>
<div class="mt-3 pt-3">
<address>
{{ c.address }}
<br />
<br />
<i class="fas fa-mobile-alt mr-2"></i>{{ c.contactno }}</address>
</div>
</div>
<div class="d-flex text-center justify-content-md-center bg-light border-top">
<div class="col-4 border-right border-bottom py-2">
<a href="javascript:void(0)" class="link">
<i class="icon-social-instagram m-r-10"></i>
{{ c.insta }}
</a>
</div>
<div class="col-4 border-right border-bottom py-2">
<a href="javascript:void(0)" class="link">
<i class="icon-social-linkedin m-r-10"></i>
{{ c.linkedin }}
</a>
</div>
<div class="col-4 py-2 border-bottom">
<a href="javascript:void(0)" class="link">
<i class="icon-social-facebook m-r-10"></i>
{{ c.facebook }}
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<ng-template #addContactModal let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Profile update</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form [formGroup]="contacts">
<div class="form-group" [ngClass]="{'has-error':formsErrors.name}">
<label for="contactname">Enter Name Here</label>
<input type="text" class="form-control" required id="contactname" formControlName="name"
(blur)='logValidationErrors(contacts)' placeholder="name here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.name">
{{formsErrors.name}}
</span>
</div>
<div class="form-group" [ngClass]="{'has-error':formsErrors.post}">
<label for="contactpost">Enter Post Here</label>
<input type="text" class="form-control" required id="contactpost" formControlName="post"
(blur)='logValidationErrors(contacts)' placeholder="post here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.post">
{{formsErrors.post}}
</span>
</div>
<div class="form-group" [ngClass]="{'has-error':formsErrors.address}">
<label for="contactadd">Enter Address Here</label>
<input type="text" class="form-control" required id="contactadd" formControlName="address"
(blur)='logValidationErrors(contacts)' placeholder="address here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.address">
{{formsErrors.address}}
</span>
</div>
<div class="form-group" [ngClass]="{'has-error':formsErrors.contactno}">
<label for="contactno">Enter Number Here</label>
<input type="text" class="form-control" required id="contactno" formControlName="contactno"
(blur)='logValidationErrors(contacts)' placeholder="Number here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.contactno">
{{formsErrors.contactno}}
</span>
</div>
<div class="form-group" [ngClass]="{'has-error':formsErrors.insta}">
<label for="contactinsta">Enter Instagram Follower Here</label>
<input type="text" class="form-control" required id="contactinsta" formControlName="insta"
(blur)='logValidationErrors(contacts)' placeholder="Instagram Follower here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.insta">
{{formsErrors.insta}}
</span>
</div>
<div class="form-group" [ngClass]="{'has-error':formsErrors.linkedin}">
<label for="contactlinked">Enter Linkedin Follower Here</label>
<input type="text" class="form-control" required id="contactlinked" formControlName="linkedin"
(blur)='logValidationErrors(contacts)' placeholder="Linkedin Follower here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.linkedin">
{{formsErrors.linkedin}}
</span>
</div>
<div class="form-group" [ngClass]="{'has-error':formsErrors.facebook}">
<label for="contactfacebook">Enter Facebook Follower Here</label>
<input type="text" class="form-control" required id="contactfacebook" formControlName="facebook"
(blur)='logValidationErrors(contacts)' placeholder="Facebook Follower here">
<span class="help-block text-danger font-14" *ngIf="formsErrors.facebook">
{{formsErrors.facebook}}
</span>
</div>
<div class="form-group">
<button type="submit" [disabled]="contacts.invalid" (click)="addContact(); modal.dismiss('Cross click');"
class="btn btn-outline-dark">Add Contact</button>
</div>
</form>
</div>
</ng-template>
import { Component, OnInit } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Contact } from './contact';
@Component({
templateUrl: './contact.component.html'
})
export class ContactComponent implements OnInit {
constructor(private modalService: NgbModal, private fb: FormBuilder) { }
closeResult: string | null = '';
contact: Contact[] = new Array();
searchText: any;
contacts: FormGroup = Object.create(null);
ValidationMessage = {
name: { required: 'Required name.' },
post: { required: 'Required post.' },
address: { required: 'Required address.' },
contactno: {
required: 'Required contactno.',
maxlength: 'Max length is 10 digits.',
pattern: 'Should be numbers only.'
},
insta: {
required: 'Required field.',
maxlength: 'Max length is 5 digits.',
pattern: 'Should be numbers only.'
},
linkedin: {
required: 'Required field.',
maxlength: 'Max length is 5 digits.',
pattern: 'Should be numbers only.'
},
facebook: {
required: 'Required field.',
maxlength: 'Max length is 5 digits.',
pattern: 'Should be numbers only.'
}
};
formsErrors = {};
open(content: string) {
this.modalService.open(content, { size: 'lg', centered: true });
}
ngOnInit() {
this.contacts = this.fb.group({
name: ['', Validators.required],
post: ['', Validators.required],
address: ['', Validators.required],
contactno: ['', [Validators.required, Validators.maxLength(10), Validators.pattern('^[0-9]*$')]],
insta: ['', [Validators.required, Validators.maxLength(5), Validators.pattern('^[0-9]*$')]],
linkedin: ['', [Validators.required, Validators.maxLength(5), Validators.pattern('^[0-9]*$')]],
facebook: ['', [Validators.required, Validators.maxLength(5), Validators.pattern('^[0-9]*$')]],
});
this.contacts.valueChanges.subscribe((d: any) => {
this.logValidationErrors(this.contacts);
});
this.contact = [
{
img: 'assets/images/users/2.jpg',
name: 'Johnathan Doe',
post: 'Web Designer',
address: '795 Folsom Ave, Suite 600 San Francisco, CADGE 94107',
contactno: 1234567890,
insta: 254,
linkedin: 54,
facebook: 154
},
{
img: 'assets/images/users/8.jpg',
name: 'Oliver Smith',
post: 'Theme Designer',
address: '55 E 11th St #1OTH, Suite 600 New York, NY, 10003 ',
contactno: 2122288403,
insta: 150,
linkedin: 14,
facebook: 165
},
{
img: 'assets/images/users/4.jpg',
name: 'George Johnson',
post: 'Front End Developer',
address: '36 W 138th St, San Francisco New York, NY, 10037',
contactno: 2122341783,
insta: 300,
linkedin: 65,
facebook: 130
},
{
img: 'assets/images/users/5.jpg',
name: 'Harry Potter',
post: 'Hacker',
address: '2289 5th Ave, Suite 600 San Francisco New York, NY, 10037',
contactno: 2124568403,
insta: 220,
linkedin: 38,
facebook: 178
},
{
img: 'assets/images/users/6.jpg',
name: 'Jack Williams',
post: 'Back End Developer',
address: '425 5th Ave, San Francisco New York, NY, 10016',
contactno: 1544568745,
insta: 650,
linkedin: 150,
facebook: 195
},
{
img: 'assets/images/users/7.jpg',
name: 'Jacob Jones',
post: 'Graphics Designer',
address: '17 Stuyvesant Walk, Suite 600 New York, NY, 10009',
contactno: 1507847890,
insta: 151,
linkedin: 29,
facebook: 160
}
];
}
logValidationErrors(group: FormGroup) {
// Object.keys(group.controls).forEach((key: string) => {
// const ac = group.get(key);
// this.formsErrors[key] = '';
// if (ac && !ac.valid && (ac.touched || ac.dirty)) {
// const message = this.ValidationMessage[key];
// for (const errorKey in ac.errors) {
// if (errorKey) {
// this.formsErrors[key] += message[errorKey] + ' ';
// }
// }
// }
// if (ac instanceof FormGroup) {
// this.logValidationErrors(ac)
// }
// })
}
addContact() {
const cnt: Contact = new Contact();
cnt.img = 'assets/images/users/6.jpg';
if (this.contacts != null) {
cnt.name = this.contacts?.get('name')?.value;
}
cnt.post = this.contacts?.get('post')?.value;
cnt.address = this.contacts?.get('address')?.value;
cnt.contactno = this.contacts?.get('contactno')?.value;
cnt.insta = this.contacts?.get('insta')?.value;
cnt.linkedin = this.contacts?.get('linkedin')?.value;
cnt.facebook = this.contacts?.get('facebook')?.value;
this.contact.push(cnt);
}
}
export class Contact {
img = '';
name = '';
post = '';
address = '';
contactno = 0;
insta = 0;
linkedin = 0;
facebook = 0;
}
import { Contact } from './contact';
export const contacts: Contact[] = [
{
firstName: 'Raj',
lastName: 'Dev',
mobile: '979797992',
home: 'jodhpur',
company: ' F creation',
work: 'AD',
notes: ' i qb inujjbw.',
imagePath: 'assets/images/users/5.jpg'
},
{
firstName: 'Mark',
lastName: 'Smith',
mobile: '989797772',
home: 'Rajasthan',
company: ' F creation',
work: 'Designer',
notes: ' noyes kns nal sjj s slhjal.',
imagePath: 'assets/images/users/2.jpg'
},
{
firstName: 'Jony',
lastName: 'Deep',
mobile: '9234567563',
home: 'LA',
company: ' F creation',
work: 'Admin',
notes: ' admin : baun ja ayu gsiko iaij sikioa...',
imagePath: 'assets/images/users/3.jpg'
},
{
firstName: 'Leonardo',
lastName: 'Caprio',
mobile: '7837937777',
home: 'NJ',
company: ' F creation',
work: 'ADMIN',
notes: 'Leo nah ujhakj jjj akkak asdkfga an a .',
imagePath: 'assets/images/users/4.jpg'
}
];
import { Injectable } from '@angular/core';
import { Contact } from './contact';
import { contacts } from './contact-data';
@Injectable()
export class ContactService {
public contacts: Contact[] = contacts;
public getContacts() {
return this.contacts;
}
}
export class Contact {
firstName = '';
lastName = '';
mobile = '';
home = '';
company = '';
work = '';
notes = '';
imagePath = '';
}
<!-- Mobile toggle button -->
<a [ngClass]="(showSidebar)?'ti-close':'ti-menu'" class="btn btn-success show-left-part d-block d-md-none"
href="javascript:void(0)" (click)="mobileSidebar()"></a>
<div class="main-part">
<!-- Left Part -->
<div class="left-part bg-white fixed-left-part" [ngClass]="{'show-panel': showSidebar}">
<div class="position-relative">
<div class="p-l-15 p-r-25 py-3 d-flex align-items-center border-bottom">
<input type="text" class="form-control" placeholder="Search Contact" [(ngModel)]='searchTerm'>
</div>
<ul class="contact-list list-style-none">
<li class="contact-item border-bottom p-3" *ngFor='let c of filterArray' [class.active]="c === selectedContact"
(click)="onSelect(c);">
<img class="rounded-circle" [src]='c.imagePath' height="40" width="40" />
<span class="ml-3 font-medium">{{c.firstName}}&nbsp;{{c.lastName}}</span>
</li>
</ul>
</div>
</div>
<!-- End Left Part -->
<!-- Right Part -->
<div class="right-part bg-white">
<div class="card">
<div class="">
<button type="button" id="btnAddContact" class="btn btn-primary" (click)='addContact()'>Add New
Contact</button>
<!-- Contact detail -->
<div *ngIf="selectedContact">
<div class="px-3 py-3 d-flex align-items-center border-bottom">
<a href="javascript: void(0);" (click)='editContact()' class="btn btn-success mr-2">
{{editSave}}
</a>
<a href="javascript: void(0);" class="btn btn-danger" (click)='deleteContact(selectedContact)'>
Delete
</a>
</div>
<div class="px-3">
<div class="row" *ngIf="show" (click)="editContact()">
<div class="col-md-2 text-center col-xl-1"><img class="rounded-circle mt-4"
[src]='selectedContact.imagePath' height="100" width="100"></div>
<div class="col-md-8">
<table class="table mt-3 table-lg table-borderless v-middle">
<tbody>
<tr>
<td class="font-bold detail-title">Name</td>
<td class="pl-2">{{selectedContact.firstName}}&nbsp;{{selectedContact.lastName}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Company</td>
<td class="pl-2">{{selectedContact.company}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Work</td>
<td class="pl-2">{{selectedContact.work}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Phone</td>
<td class="pl-2">{{selectedContact.mobile}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Address</td>
<td class="pl-2">{{selectedContact.home}}</td>
</tr>
<tr>
<td class="font-bold detail-title">Note</td>
<td class="pl-2">{{selectedContact.notes}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mt-4 row" *ngIf="!show">
<div class="col-md-2 text-center col-xl-1"><img class="rounded-circle mt-4 flex-shrink-0"
[src]='selectedContact.imagePath' height="100" width="100"></div>
<div class="col-md-8">
<table class="ml-4 table table-borderless v-middle">
<tbody>
<tr>
<td class="font-bold detail-title">Name</td>
<td class="d-flex">
<input type="text" [(ngModel)]="selectedContact.firstName" class="form-control">
<input type="text" [(ngModel)]="selectedContact.lastName" class="form-control ml-2"></td>
</tr>
<tr>
<td class="font-bold detail-title">Company</td>
<td><input type="text" [(ngModel)]="selectedContact.company" class="form-control"></td>
</tr>
<tr>
<td class="font-bold detail-title">Work</td>
<td><input type="text" [(ngModel)]="selectedContact.work" class="form-control"></td>
</tr>
<tr>
<td class="font-bold detail-title">Phone</td>
<td><input type="text" [(ngModel)]="selectedContact.mobile" class="form-control" maxlength="10">
</td>
</tr>
<tr>
<td class="font-bold detail-title">Address</td>
<td><input type="text" [(ngModel)]="selectedContact.home" class="form-control"></td>
</tr>
<tr>
<td class="font-bold detail-title">Note</td>
<td><textarea [(ngModel)]="selectedContact.notes" class="form-control"></textarea></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- End Contact detail -->
</div>
</div>
</div>
<!-- End Right Part -->
</div>
.detail-title {
width: 80px;
position: relative;
&:after {
content: ":";
position: absolute;
right: 0px;
}
}
.contact-list {
.contact-item {
&:hover {
cursor: pointer;
}
&.active {
background-color: #e9ecef;
}
}
}
#btnAddContact {
position: absolute;
right: 15px;
top: 15px;
}
import { Component, OnInit } from '@angular/core';
import { Contact } from './contact';
import { ContactService } from './contact.service';
@Component({
selector: 'app-contacts',
templateUrl: './contacts.component.html',
styleUrls: ['./contacts.component.scss']
})
export class ContactsComponent implements OnInit {
public showSidebar = false;
contacts = this.contactService.getContacts();
selectedContact: Contact | null = null;
show = true;
editSave = 'Edit';
filterArray: Contact[] = [];
_searchTerm = '';
mobileSidebar() {
this.showSidebar = !this.showSidebar;
}
get searchTerm(): string {
return this._searchTerm;
}
set searchTerm(val: string) {
this._searchTerm = val;
this.filterArray = this.filter(val);
}
filter(v: string) {
return this.contacts.filter(x => x.firstName.toLowerCase().
indexOf(v.toLowerCase()) !== -1 || x.lastName.toLowerCase().indexOf(v.toLowerCase()) !== -1);
}
constructor(public contactService: ContactService) {
}
ngOnInit() {
this.filterArray = this.contacts;
if (this.contacts.length > 0) {
this.onSelect(this.contacts[0]);
}
}
onSelect(contact: Contact) {
this.selectedContact = contact;
}
editContact() {
if (this.editSave === 'Save') {
this.show = true;
this.editSave = 'Edit';
} else {
this.show = false;
this.editSave = 'Save';
}
}
addContact() {
this.contacts.push({
firstName: 'Enter',
lastName: 'Name',
mobile: '',
home: '',
company: '',
work: '',
notes: '',
imagePath: 'assets/images/users/1.jpg'
});
this.filterArray = this.contacts;
this.selectedContact = this.filterArray[this.filterArray.length - 1];
this.editContact();
}
deleteContact(i: Contact) {
this.contacts = this.contacts.filter(con => con.firstName !== i.firstName);
this.filterArray = this.contacts.filter(con => con.firstName !== i.firstName);
// if(this.filterArray.length>0)
this.selectedContact = null;
}
}
<div class="event-dialog-wrapper">
<mat-toolbar matDialogTitle class="mat-primary m-0">
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
<span class="title dialog-title">{{dialogTitle}}</span>
<button mat-icon-button (click)="dialogRef.close()" aria-label="Close dialog">
<mat-icon>close</mat-icon>
</button>
</div>
</mat-toolbar>
<div mat-dialog-content class="p-16 m-0">
<form name="eventForm" [formGroup]="eventForm" class="event-form" fxFlex>
<div fxLayout="row wrap" fxLayout.lt-sm="column">
<div fxFlex="100">
<mat-form-field class="full-width">
<input
matInput
name="title"
formControlName="title"
placeholder="Title"
required>
</mat-form-field>
</div>
<div fxLayout="row" fxLayout.lt-sm="column" fxFlex="100" formGroupName="color">
<mat-form-field fxFlex>
<input
matInput
class="color-picker-input"
name="primaryColor"
formControlName="primary"
placeholder="Primary color"
type="color"
[style.background]="event.color.primary"
(colorPickerChange)="eventForm.patchValue({color:{primary: event.color.primary}})"
/>
</mat-form-field>
<span fxFlex="16px"></span>
<mat-form-field fxFlex>
<input
matInput
class="color-picker-input"
name="secondaryColor"
formControlName="secondary"
placeholder="Secondary color"
type="color"
[style.background]="event.color.secondary"
(colorPickerChange)="eventForm.patchValue({color:{secondary: event.color.secondary}})"
/>
</mat-form-field>
</div>
<div fxLayout="row" fxLayout.lt-sm="column" fxFlex="100">
<mat-form-field fxFlex>
<input
matInput
[matDatepicker]="startDateDP"
placeholder="Start Date"
name="startDate"
formControlName="start">
<mat-datepicker-toggle matSuffix [for]="startDateDP"></mat-datepicker-toggle>
<mat-datepicker #startDateDP></mat-datepicker>
</mat-form-field>
<span fxFlex="16px"></span>
<mat-form-field fxFlex>
<input
matInput
[matDatepicker]="endDateDP"
placeholder="End Date"
name="endDate"
formControlName="end">
<mat-datepicker-toggle matSuffix [for]="endDateDP"></mat-datepicker-toggle>
<mat-datepicker #endDateDP></mat-datepicker>
</mat-form-field>
</div>
<div fxLayout="column" fxFlex="100">
<mat-form-field formGroupName="meta" class="">
<input
matInput
name="location"
formControlName="location"
placeholder="Location">
</mat-form-field>
<mat-form-field formGroupName="meta" class="">
<textarea
matInput
formControlName="notes"
placeholder="Notes"
max-rows="4">
</textarea>
</mat-form-field>
</div>
</div>
</form>
</div>
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
<button
mat-raised-button
color="primary"
(click)="dialogRef.close({action: 'save', event: eventForm.value})"
[disabled]="eventForm.invalid"
aria-label="SAVE">
Save
</button>
<button
*ngIf="action ==='edit'"
mat-icon-button color="warn"
(click)="dialogRef.close({action: 'delete'})"
aria-label="Delete"
matTooltip="Delete">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
\ No newline at end of file
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { CalendarEvent } from 'angular-calendar';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { EgretCalendarEvent} from '../event.model';
interface DialogData {
event?: CalendarEvent,
action?: string,
date?: Date
}
@Component({
selector: 'app-calendar-form-dialog',
templateUrl: './calendar-form-dialog.component.html',
styleUrls: ['./calendar-form-dialog.component.scss']
})
export class CalendarFormDialogComponent implements OnInit {
event:any
dialogTitle: string;
eventForm: FormGroup;
action: any;
constructor(
public dialogRef: MatDialogRef<CalendarFormDialogComponent>,
@Inject(MAT_DIALOG_DATA) private data: DialogData,
private formBuilder: FormBuilder
) {
this.event = data.event;
this.action = data.action;
if (this.action === 'edit') {
this.dialogTitle = this.event.title;
} else {
this.dialogTitle = 'Add Event';
this.event = new EgretCalendarEvent({
start: data.date,
end: data.date
});
}
// console.log(data);
this.eventForm = this.buildEventForm(this.event);
}
ngOnInit() {
}
buildEventForm(event: any) {
return new FormGroup({
_id: new FormControl(event._id),
title: new FormControl(event.title),
start: new FormControl(event.start),
end: new FormControl(event.end),
allDay: new FormControl(event.allDay),
color: this.formBuilder.group({
primary: new FormControl(event.color.primary),
secondary: new FormControl(event.color.secondary)
}),
meta: this.formBuilder.group({
location: new FormControl(event.meta.location),
notes: new FormControl(event.meta.notes)
}),
draggable:new FormControl(true),
});
}
}
import { CalendarEventAction, CalendarEvent } from 'angular-calendar';
import {
startOfDay,
endOfDay,
subDays,
addDays,
endOfMonth,
isSameDay,
isSameMonth,
addHours
} from 'date-fns';
export class EgretCalendarEvent implements CalendarEvent {
_id?: string;
start: Date;
end: Date ;
title: string;
color?: {
primary: string;
secondary: string;
};
actions?: CalendarEventAction[];
allDay?: boolean;
cssClass?: string;
resizable?: {
beforeStart?: boolean;
afterEnd?: boolean;
};
draggable?: boolean;
meta?: {
location: string,
notes: string
};
constructor(data:any) {
data = data || {};
this.start = new Date(data.start) || startOfDay(new Date());
this.end = new Date(data.end);
this._id = data._id || '';
this.title = data.title || '';
this.color = {
primary: data.color && data.color.primary || '#247ba0',
secondary: data.color && data.color.secondary || '#D1E8FF'
};
this.draggable = data.draggable || true;
this.resizable = {
beforeStart: data.resizable && data.resizable.beforeStart || true,
afterEnd: data.resizable && data.resizable.afterEnd || true
};
this.actions = data.actions || [];
this.allDay = data.allDay || false;
this.cssClass = data.cssClass || '';
this.meta = {
location: data.meta && data.meta.location || '',
notes: data.meta && data.meta.notes || ''
};
}
}
<div class="card">
<div class="card-body">
<!-- ============================================================== -->
<!-- Top Buttons -->
<!-- ============================================================== -->
<h3>
Angular Calendar
<button class="btn btn-primary float-right" (click)="addEvent()">
Add New Event
</button>
<div class="clearfix"></div>
</h3>
<hr>
<div class="pt-3 row">
<div class="col-md-4">
<div class="btn-group">
<div class="btn btn-success" mwlCalendarPreviousView [view]="view" [(viewDate)]="viewDate"
(viewDateChange)="activeDayIsOpen = false">
Previous </div>
<div class="btn btn-outline-secondary" mwlCalendarToday [(viewDate)]="viewDate"> Today </div>
<div class="btn btn-info" mwlCalendarNextView [view]="view" [(viewDate)]="viewDate"
(viewDateChange)="activeDayIsOpen = false">
Next </div>
</div>
</div>
<div class="col-md-4 text-center">
<h3>{{ viewDate | calendarDate:(view + 'ViewTitle'):'en' }}</h3>
</div>
<div class="col-md-4 text-right">
<div class="btn-group">
<div class="btn btn-info" (click)="setView(CalendarView.Month)" [class.active]="view === CalendarView.Month">
Month </div>
<div class="btn btn-success" (click)="setView(CalendarView.Week)" [class.active]="view === CalendarView.Week">
Week </div>
<div class="btn btn-warning" (click)="setView(CalendarView.Day)" [class.active]="view === CalendarView.Day">
Day </div>
</div>
</div>
</div>
<br>
<!-- ============================================================== -->
<!-- Calander Area -->
<!-- ============================================================== -->
<div [ngSwitch]="view">
<mwl-calendar-month-view *ngSwitchCase="CalendarView.Month" [viewDate]="viewDate" [events]="events"
[refresh]="refresh" [activeDayIsOpen]="activeDayIsOpen" (dayClicked)="dayClicked($event.day)"
(eventClicked)="handleEvent('Clicked', $event.event)" (eventTimesChanged)="eventTimesChanged($event)">
</mwl-calendar-month-view>
<mwl-calendar-week-view *ngSwitchCase="CalendarView.Week" [viewDate]="viewDate" [events]="events"
[refresh]="refresh" (eventClicked)="handleEvent('Clicked', $event.event)"
(eventTimesChanged)="eventTimesChanged($event)">
</mwl-calendar-week-view>
<mwl-calendar-day-view *ngSwitchCase="CalendarView.Day" [viewDate]="viewDate" [events]="events"
[refresh]="refresh" (eventClicked)="handleEvent('Clicked', $event.event)"
(eventTimesChanged)="eventTimesChanged($event)">
</mwl-calendar-day-view>
</div>
<br /><br />
<hr>
<br />
<!-- ============================================================== -->
<!-- Edit Evenets -->
<!-- ============================================================== -->
<h3>
Edit events
<button class="btn btn-primary float-right" (click)="addEvent()">
Add new
</button>
<div class="clearfix"></div>
</h3>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Primary color</th>
<th>Secondary color</th>
<th>Starts at</th>
<th>Ends at</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let event of events">
<td>
<input type="text" class="form-control" [(ngModel)]="event.title" (keyup)="refresh.next()" />
</td>
<td>
<input type="color" [(ngModel)]="event.color.primary" (change)="refresh.next()" />
</td>
<td>
<input type="color" [(ngModel)]="event.color.secondary" (change)="refresh.next()" />
</td>
<td>
<input class="form-control bg-white" type="text" mwlFlatpickr [(ngModel)]="event.start"
(ngModelChange)="refresh.next()" [altInput]="true" [convertModelValue]="true" [enableTime]="true"
dateFormat="Y-m-dTH:i" altFormat="F j, Y H:i" placeholder="Not set" />
</td>
<td>
<input class="form-control bg-white" type="text" mwlFlatpickr [(ngModel)]="event.end"
(ngModelChange)="refresh.next()" [altInput]="true" [convertModelValue]="true" [enableTime]="true"
dateFormat="Y-m-dTH:i" altFormat="F j, Y H:i" placeholder="Not set" />
</td>
<td>
<button class="btn btn-danger" (click)="deleteEvent(event)">
Delete
</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- ============================================================== -->
<!-- Event Popup -->
<!-- ============================================================== -->
<ng-template #modalContent let-close="close">
<div class="modal-header">
<h5 class="modal-title">Event {{ modalData?.action }}</h5>
<button type="button" class="close" (click)="close()">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" >
{{ modalData?.action }}
<!-- Event if Edited -->
<div *ngIf="modalData?.action === 'Edit'">
<h5>Event Title</h5>
<input type="text" class="form-control" [(ngModel)]="modalData?.event.title" (keyup)="refresh.next()" />
<div class="row">
<div class="col-md-12">
<h5 class="mt-3">Event Color</h5>
<input type="color" [(ngModel)]="modalData?.event.color.primary" (change)="refresh.next()"
width="500px" />
</div>
</div>
<div class="row">
<div class="col-md-6">
<h5 class="mt-3">Event Start</h5>
<input class="form-control bg-white" type="text" mwlFlatpickr [(ngModel)]="modalData?.event.start"
(ngModelChange)="refresh.next()" [altInput]="true" [convertModelValue]="true" [enableTime]="true"
dateFormat="Y-m-dTH:i" altFormat="F j, Y H:i" placeholder="Not set" />
</div>
<div class="col-md-6">
<h5 class="mt-3">Event End</h5>
<input class="form-control bg-white" type="text" mwlFlatpickr [(ngModel)]="modalData?.event.end"
(ngModelChange)="refresh.next()" [altInput]="true" [convertModelValue]="true" [enableTime]="true"
dateFormat="Y-m-dTH:i" altFormat="F j, Y H:i" placeholder="Not set" />
</div>
<button type="button" class="btn btn-primary mt-4 ml-3" (click)="close()">
OK
</button>
</div>
</div>
</div>
</ng-template>
<ng-template #modalContentAdd let-close="close">
<div class="modal-header">
<h5 class="modal-title">Add Event</h5>
<button type="button" class="close" (click)="close()">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form #add="ngForm" (ngSubmit)="onSubmit(add)">
<div class="modal-body">
<h5>Event Title</h5>
<input type="text" class="form-control" (keyup)="refresh.next()" required name="title" ngModel />
<h5 class="mt-3">Event Color</h5>
<input type="color" (change)="refresh.next()" name="color" ngModel />
<div class="row">
<div class="col-md-6">
<h5 class="mt-3">Event Start</h5>
<input class="form-control bg-white" type="text" name="startDate" ngModel mwlFlatpickr
(ngModelChange)="refresh.next()" [altInput]="true" [convertModelValue]="true" [enableTime]="true"
dateFormat="Y-m-dTH:i" altFormat="F j, Y H:i" placeholder="Not set" required/>
</div>
<div class="col-md-6">
<h5 class="mt-3">Event End</h5>
<input class="form-control bg-white" type="text" name="endDate" ngModel mwlFlatpickr
(ngModelChange)="refresh.next()" [altInput]="true" [convertModelValue]="true" [enableTime]="true"
dateFormat="Y-m-dTH:i" altFormat="F j, Y H:i" placeholder="Not set" />
</div>
<button type="submit" class="btn btn-primary mt-4 ml-3" [disabled]="add.invalid">Add Event</button>
</div>
</div>
</form>
</ng-template>
</div>
</div>
\ No newline at end of file
input[type="color"] {
-webkit-appearance: none;
border: none;
width: 100%;
}
input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: none;
}
\ No newline at end of file
import {
Component,
ChangeDetectionStrategy,
ViewChild,
TemplateRef
} from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import {
startOfDay,
endOfDay,
subDays,
addDays,
endOfMonth,
isSameDay,
isSameMonth,
addHours
} from 'date-fns';
import { Subject } from 'rxjs';
import {
CalendarEvent,
CalendarEventAction,
CalendarEventTimesChangedEvent,
CalendarView,
} from 'angular-calendar';
import { NgForm } from '@angular/forms';
const colors: any = {
red: {
primary: '#ff5c6c',
secondary: '#FAE3E3'
},
blue: {
primary: '#1e90ff',
secondary: '#D1E8FF'
},
yellow: {
primary: '#24d2b5',
secondary: '#FDF1BA'
}
};
@Component({
selector: 'app-fullcalendar',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './fullcalendar.component.html',
styleUrls: ['./fullcalendar.component.scss']
})
export class FullcalendarComponent {
@ViewChild('modalContent', { static: true }) modalContent!: TemplateRef<any>;
@ViewChild('modalContentAdd', { static: true }) modalContentAdd!: TemplateRef<any>;
view: CalendarView = CalendarView.Month;
CalendarView = CalendarView;
viewDate: Date = new Date();
/*/////////////////////////////////////
Event action buttons
////////////////////////////////////*/
actions: CalendarEventAction[] = [
{
label: '<span class="badge badge-info ml-1"><i class="ti-pencil"></i></span>',
a11yLabel: 'Edit',
onClick: ({ event }: { event: CalendarEvent }): void => {
this.handleEvent('Edit', event);
},
},
{
label: '<span class="badge badge-danger ml-1"><i class="ti-trash"></i></span>',
a11yLabel: 'Delete',
onClick: ({ event }: { event: CalendarEvent }): void => {
this.events = this.events.filter((iEvent) => iEvent !== event);
this.handleEvent('Deleted', event);
},
},
];
refresh: Subject<any> = new Subject();
/*/////////////////////////////////////
Default Events added
////////////////////////////////////*/
events: CalendarEvent[] = [
{
start: subDays(startOfDay(new Date()), 1),
end: addDays(new Date(), 1),
title: 'A 3 day event',
color: colors.red,
actions: this.actions,
allDay: true,
resizable: {
beforeStart: true,
afterEnd: true,
},
draggable: true,
},
{
start: startOfDay(new Date()),
title: 'An event with no end date',
color: colors.yellow,
actions: this.actions,
},
{
start: subDays(endOfMonth(new Date()), 3),
end: addDays(endOfMonth(new Date()), 3),
title: 'A long event that spans 2 months',
color: colors.blue,
allDay: true,
},
{
start: addHours(startOfDay(new Date()), 2),
end: addHours(new Date(), 2),
title: 'A draggable and resizable event',
color: colors.yellow,
actions: this.actions,
resizable: {
beforeStart: true,
afterEnd: true,
},
draggable: true,
},
];
activeDayIsOpen: boolean = true;
modalData!: {
action: string;
event: CalendarEvent;
};
constructor(private modal: NgbModal) {
}
/*/////////////////////////////////////
On Day Click
////////////////////////////////////*/
dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void {
if (isSameMonth(date, this.viewDate)) {
if (
(isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) ||
events.length === 0
) {
this.activeDayIsOpen = false;
} else {
this.activeDayIsOpen = true;
}
this.viewDate = date;
}
}
eventTimesChanged({
event,
newStart,
newEnd,
}: CalendarEventTimesChangedEvent): void {
this.events = this.events.map((iEvent) => {
if (iEvent === event) {
return {
...event,
start: newStart,
end: newEnd,
};
}
return iEvent;
});
this.handleEvent('Dropped or resized', event);
}
handleEvent(action: string, event: CalendarEvent): void {
this.modalData = { event, action };
this.modal.open(this.modalContent, { size: 'lg' });
}
/*/////////////////////////////////////
Add Event
////////////////////////////////////*/
addEvent(): void {
this.modal.open(this.modalContentAdd, {
size: 'lg',
});
}
/*/////////////////////////////////////
Delete Event
////////////////////////////////////*/
deleteEvent(eventToDelete: CalendarEvent) {
this.events = this.events.filter((event) => event !== eventToDelete);
}
setView(view: CalendarView) {
this.view = view;
}
closeOpenMonthViewDay() {
this.activeDayIsOpen = false;
}
onSubmit(data: NgForm) {
this.events = [
...this.events,
{
title: data.value.title,
start: data.value.startDate,
end: data.value.endDate,
color: data.value.color,
actions: this.actions,
allDay: true,
resizable: {
beforeStart: true,
afterEnd: true,
},
draggable: true,
},
];
this.modal.dismissAll();
}
}
<div class="card">
<div class="card-body">
<form #invoiceForm='ngForm'>
<div class="row mb-3">
<div class="col-md-6">
<h4 class="mb-0">Invoice Id : # <span name="id" [(ngModel)]='invoice.id' ngDefaultControl>
{{invoice.id}}</span></h4>
</div>
<div class="col-md-6 mt-3 mt-md-0">
<div class="row justify-content-end">
<div class="col-lg-3 col-md-4 col-6">
<a routerLink='/apps/invoice'
class="btn btn-outline-danger shadow-sm font-medium btn-block">
Cancel
</a>
</div>
<div class="col-lg-3 col-md-4 col-6">
<button type="button" class="btn btn-outline-success shadow-sm font-medium btn-block"
(click)=saveDetail() [disabled]="addForm.invalid">Save</button>
</div>
</div>
</div>
</div>
<div class="d-flex align-items-center border-top pt-3 pb-3 border-bottom">
<div>
<h5>Order Status : </h5>
<select class="form-control mt-2" name="satus" [(ngModel)]='invoice.status'>
<option value="Pending">Pending</option>
<option value="Shipped">Shipped</option>
<option value="Delivered">Delivered</option>
</select>
</div>
<div class="ml-auto">
<h5>Order Date</h5>
<span name="date" [(ngModel)]='invoice.orderDate'
ngDefaultControl>{{invoice.orderDate | date: 'dd-MM-yyyy'}}</span>
</div>
</div>
<div class="row mt-4">
<div class="col-md-6">
<div class="form-group">
<input type="text" class="form-control" placeholder="Bill From" name="from"
[(ngModel)]='invoice.billFrom'>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" class="form-control" placeholder="Bill To" name="to"
[(ngModel)]='invoice.billTo'>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<textarea class="form-control" rows="3" placeholder="Enter From Address" name="fromAddress"
[(ngModel)]='invoice.billFromAddress'></textarea>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<textarea class="form-control" rows="3" placeholder="Enter To Address" name="toAddress"
[(ngModel)]='invoice.billToAddress'></textarea>
</div>
</div>
</div>
</form>
<div [formGroup]="addForm">
<div class="table-responsive">
<table class="table table-hover table-bordered no-wrap v-middle">
<thead>
<tr>
<th class="border-bottom-0">#</th>
<th class="border-bottom-0">Item Name</th>
<th class="border-bottom-0">Unit Price</th>
<th class="border-bottom-0">Units</th>
<th class="border-bottom-0">Unit Total Price</th>
<th class="border-bottom-0"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of addForm.get('rows')?.controls;let index = index;">
<td>
{{index+1}}
</td>
<td>
<input type="text" class="form-control" [formControl]="row.get('itemName')"
(input)="itemsChanged()">
</td>
<td>
<input type="number" class="form-control" min=1 [formControl]="row.get('unitPrice')"
(input)="itemsChanged()">
</td>
<td>
<input type="number" class="form-control" min=1 [formControl]="row.get('units')"
(input)="itemsChanged()">
</td>
<td>
<input disabled class="form-control" [formControl]="row.get('itemTotal')"
[value]="row.get('unitPrice').value * row.get('units').value">
</td>
<td>
<span *ngIf='index > 0'>
<button type="button" class="btn btn-danger"
(click)="onRemoveRow(index)">Remove</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="text-right">
<button type="button" class="btn btn-info" (click)="onAddRow()" [disabled]="addForm.invalid"
*ngIf="addForm.get('rows')">Add row</button>
<div class="border-top mt-3 pt-3">
<h5><span>Sub total </span> : {{subTotal}}</h5>
</div>
<div class="border-top mt-3 pt-3">
<h5>Total Vat:</h5>
<div class="row justify-content-end">
<div class="col-lg-2 col-md-4">
<div class="input-group mb-3">
<input type="number" class="form-control" value="10">
<div class="input-group-append">
<span class="input-group-text">%</span>
<span class="input-group-text bg-white font-medium">: {{vat}}</span>
</div>
</div>
</div>
</div>
</div>
<hr />
<h3><span class="font-weight-bold mr-2">Total:</span>${{grandTotal}} </h3>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AddInvoiceComponent } from './add-invoice.component';
describe('AddInvoiceComponent', () => {
let component: AddInvoiceComponent;
let fixture: ComponentFixture<AddInvoiceComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddInvoiceComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddInvoiceComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl, FormArray, NgForm } from '@angular/forms';
import { order, InvoiceList } from '../invoice';
import { InvoiceService } from '../invoice.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-add-invoice',
templateUrl: './add-invoice.component.html',
styleUrls: ['./add-invoice.component.css']
})
export class AddInvoiceComponent implements OnInit {
// selected = 'option1';
// date = new Date();
addForm: FormGroup;
rows: FormArray;
invoice: InvoiceList = new InvoiceList();
///////////////////////////////////////////////////////////
subTotal = 0;
vat = 0;
grandTotal = 0;
constructor(private fb: FormBuilder, private invoiceService: InvoiceService,private router: Router) {
this.invoice.id =
Math.max.apply(Math, this.invoiceService.getInvoiceList().map(function (o) { return o.id; })) + 1;
this.invoice.status = 'Pending'
///////////////////////////////////////////////////////////
this.addForm = this.fb.group({
});
this.rows = this.fb.array([]);
this.addForm.addControl('rows', this.rows);
this.rows.push(this.createItemFormGroup());
}
ngOnInit(): void {
}
////////////////////////////////////////////////////////////////////////////////////
onAddRow() {
this.rows.push(this.createItemFormGroup());
}
onRemoveRow(rowIndex: number) {
let totalCostOfItem = this.addForm.get('rows')?.value[rowIndex].unitPrice *
this.addForm.get('rows')?.value[rowIndex].units;
this.subTotal = this.subTotal - totalCostOfItem;
this.vat = this.subTotal / 10;
this.grandTotal = this.subTotal + this.vat;
this.rows.removeAt(rowIndex);
}
createItemFormGroup(): FormGroup {
return this.fb.group({
itemName: ['', Validators.required],
units: ['', Validators.required],
unitPrice: ['', Validators.required],
itemTotal: ['0']
});
}
itemsChanged() {
let total: number = 0;
for (let t = 0; t < (<FormArray>this.addForm.get('rows')).length; t++) {
if (this.addForm.get('rows')?.value[t].unitPrice != '' && this.addForm.get('rows')?.value[t].units) {
total = (this.addForm.get('rows')?.value[t].unitPrice * this.addForm.get('rows')?.value[t].units) + total;
}
}
this.subTotal = total;
this.vat = this.subTotal / 10;
this.grandTotal = this.subTotal + this.vat;
}
////////////////////////////////////////////////////////////////////
saveDetail() {
this.invoice.grandTotal = this.grandTotal;
this.invoice.totalCost = this.subTotal;
this.invoice.vat = this.vat;
for (let t = 0; t < (<FormArray>this.addForm.get('rows')).length; t++) {
let o: order = new order();
o.itemName = this.addForm.get('rows')?.value[t].itemName;
o.unitPrice = this.addForm.get('rows')?.value[t].unitPrice;
o.units = this.addForm.get('rows')?.value[t].units;
o.unitTotalPrice = o.units * o.unitPrice;
this.invoice.orders.push(o);
}
this.invoiceService.addInvoice(this.invoice);
alert('New Invoice Added !!');
this.router.navigate(['/apps/invoice']);
}
}
<div class="card card-body">
<form #invoiceForm='ngForm'>
<div class="row mb-3">
<div class="col-md-6">
<h4 class="mb-0">Invoice Id : # <span name="id" [(ngModel)]='invoice.id' ngDefaultControl>
{{invoice.id}}</span></h4>
</div>
<div class="col-md-6 mt-3 mt-md-0">
<div class="row justify-content-end">
<div class="col-lg-3 col-md-4 col-6">
<a routerLink='/apps/invoice' class="btn btn-outline-danger shadow-sm font-medium btn-block">
Cancel
</a>
</div>
<div class="col-lg-3 col-md-4 col-6">
<button type="button" class="btn btn-outline-success shadow-sm font-medium btn-block"
(click)=saveDetail()>Save</button>
</div>
</div>
</div>
</div>
<div class="d-flex align-items-center border-top pt-3 pb-3 border-bottom">
<div>
<h5>Order Status : </h5>
<select class="form-control mt-2" name="satus" [(ngModel)]='invoice.status'>
<option value="Pending">Pending</option>
<option value="Shipped">Shipped</option>
<option value="Delivered">Delivered</option>
</select>
</div>
<div class="ml-auto">
<h5>Order Date</h5>
<span name="date" [(ngModel)]='invoice.orderDate'
ngDefaultControl>{{invoice.orderDate | date: 'dd-MM-yyyy'}}</span>
</div>
</div>
<div class="row mt-4">
<div class="col-md-6">
<div class="form-group">
<input type="text" class="form-control" placeholder="Bill From" name="from"
[(ngModel)]='invoice.billFrom'>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" class="form-control" placeholder="Bill To" name="to"
[(ngModel)]='invoice.billTo'>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<textarea class="form-control" rows="3" placeholder="Enter From Address" name="fromAddress"
[(ngModel)]='invoice.billFromAddress'></textarea>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<textarea class="form-control" rows="3" placeholder="Enter To Address" name="toAddress"
[(ngModel)]='invoice.billToAddress'></textarea>
</div>
</div>
</div>
</form>
<form [formGroup]="addForm">
<div class="table-responsive">
<table id="tblAdd" class="table table-hover table-bordered no-wrap v-middle">
<thead>
<tr>
<th class="border-bottom-0">#</th>
<th class="border-bottom-0">Item Name</th>
<th class="border-bottom-0">Unit Price</th>
<th class="border-bottom-0">Units</th>
<th class="border-bottom-0">Unit Total Price</th>
<th class="border-bottom-0"></th>
</tr>
</thead>
<tbody formArrayName="item" *ngFor="let a of addForm.get('item')?.controls;let i=index">
<tr [formGroupName]="i">
<td>
{{i+1}}
</td>
<td>
<input type="text" [id]="'txtNameControl'+i" class="form-control"
placeholder="Enter Item Name" formControlName="itemName" (input)="itemsChanged()">
</td>
<td>
<input type="number" [id]="'txtCostControl'+i" class="form-control"
placeholder="Enter Item Price" formControlName="itemCost" (input)="itemsChanged()">
</td>
<td>
<input type="number" [id]="'txtTotalControl'+i" class="form-control"
placeholder="Enter Item" formControlName="itemSold" (input)="itemsChanged()">
</td>
<td>
<input type="number" formControlName="itemTotal" [id]="'txtitemTotalControl'+i"
[value]="addForm.get('item').value[this.i].itemCost * addForm.get('item').value[this.i].itemSold"
class="form-control" disabled />
</td>
<td>
<button type="button" *ngIf="addForm.get('item')?.length > 1" class="btn btn-danger btn-sm"
(click)="btnRemoveClick(i)">
<span class="glyphicon glyphicon-remove">Delete</span>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="text-right">
<button type="button" class="btn btn-info" (click)="btnAddItemClick()"
[disabled]="addForm.get('item')?.invalid">Add Item</button>
<div class="border-top mt-3 pt-3">
<h5><span>Sub total </span> : {{subTotal}}</h5>
</div>
<div class="border-top mt-3 pt-3">
<h5>Total Vat:</h5>
<div class="row justify-content-end">
<div class="col-lg-2 col-md-4">
<div class="input-group mb-3">
<input type="number" class="form-control" value="10">
<div class="input-group-append">
<span class="input-group-text">%</span>
<span class="input-group-text bg-white font-medium">: {{vat}}</span>
</div>
</div>
</div>
</div>
</div>
<hr />
<h3><span class="font-weight-bold mr-2">Total:</span>${{grandTotal}} </h3>
</div>
</form>
</div>
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EditInvoiceComponent } from './edit-invoice.component';
describe('EditInvoiceComponent', () => {
let component: EditInvoiceComponent;
let fixture: ComponentFixture<EditInvoiceComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EditInvoiceComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EditInvoiceComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { InvoiceService } from '../invoice.service';
import { InvoiceList, order } from '../invoice';
import { FormGroup, FormArray, FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-edit-invoice',
templateUrl: './edit-invoice.component.html',
styleUrls: ['./edit-invoice.component.css']
})
export class EditInvoiceComponent implements OnInit {
id: any;
invoice: InvoiceList;
addForm: FormGroup;
subTotal = 0;
vat = 0;
grandTotal = 0;
constructor(activatedRouter: ActivatedRoute, private invoiceService: InvoiceService,
private router: Router, private fb: FormBuilder) {
this.id = activatedRouter.snapshot.paramMap.get('id');
this.invoice = this.invoiceService.getInvoiceList().filter(x => x.id === +this.id)[0];
this.subTotal = this.invoice.totalCost;
this.vat = this.invoice.vat;
this.grandTotal = this.invoice.grandTotal;
this.addForm = this.fb.group({
item: this.fb.array([
this.itemControl()
]),
});
this.fillAddControls();
}
ngOnInit(): void {
}
itemControl(): FormGroup {
return this.fb.group({
itemName: ['', Validators.required],
itemCost: ['', Validators.required],
itemSold: ['', Validators.required],
itemTotal: ['0']
})
}
fillAddControls() {
this.addForm.setControl('item', this.setItem(this.invoice.orders));
}
setItem(order: any): FormArray {
const fa = new FormArray([]);
order.forEach((s: any) => {
fa.push(this.fb.group({
itemName: s.itemName,
itemCost: s.unitPrice,
itemSold: s.units,
itemTotal: s.unitTotalPrice
}));
});
return fa;
}
btnAddItemClick(): void {
(<FormArray>this.addForm.get('item')).push(this.itemControl());
}
btnRemoveClick(i: number): void {
let totalCostOfItem = this.addForm.get('item')?.value[i].itemCost * this.addForm.get('item')?.value[i].itemSold;
this.subTotal = this.subTotal - totalCostOfItem;
this.vat = this.subTotal / 10;
this.grandTotal = this.subTotal + this.vat;
(<FormArray>this.addForm.get('item')).removeAt(i);
}
//////////////////////////////////////////////////////////////////////////////
itemsChanged() {
let total: number = 0;
for (let t = 0; t < (<FormArray>this.addForm.get('item')).length; t++) {
if (this.addForm.get('item')?.value[t].itemCost != '' && this.addForm.get('item')?.value[t].itemSold) {
total = (this.addForm.get('item')?.value[t].itemCost * this.addForm.get('item')?.value[t].itemSold) + total;
}
}
this.subTotal = total;
this.vat = this.subTotal / 10;
this.grandTotal = this.subTotal + this.vat;
}
saveDetail() {
this.invoice.grandTotal = this.grandTotal;
this.invoice.totalCost = this.subTotal;
this.invoice.vat = this.vat;
this.invoice.orders = [];
for (let t = 0; t < (<FormArray>this.addForm.get('item')).length; t++) {
let o: order = new order();
o.itemName = this.addForm.get('item')?.value[t].itemName;
o.unitPrice = this.addForm.get('item')?.value[t].itemCost;
o.units = this.addForm.get('item')?.value[t].itemSold;
o.unitTotalPrice = o.units * o.unitPrice;
this.invoice.orders.push(o);
}
this.invoiceService.updateInvoice(this.invoice.id, this.invoice);
alert('Invoice Updated !!');
this.router.navigate(['/apps/invoice']);
}
}
import { InvoiceList } from './invoice';
export const invoceLists: InvoiceList[] = [
{
id: 101,
billFrom: 'Pineapple Inc.',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'Redq Inc.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date(),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Shipped',
completed: false,
isSelected: false
},
{
id: 102,
billFrom: 'Pineapple.',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'ME Inc.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date(),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Delivered',
completed: false,
isSelected: false
},
{
id: 103,
billFrom: 'Incorporation.',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'Redirwed.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [
{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date(),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Pending',
completed: false,
isSelected: false
},
{
id: 104,
billFrom: 'PineappleTimes .',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'RFc.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date(),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Shipped',
completed: false,
isSelected: false
},
{
id: 105,
billFrom: 'Fortune Creation',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'Soft solution.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date('2020-10-15'),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Delivered',
completed: false,
isSelected: false
},
{
id: 106,
billFrom: 'PineappleTimes .',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'RFc.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date(),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Shipped',
completed: false,
isSelected: false
},
{
id: 107,
billFrom: 'Fortune Creation',
billFromEmail: 'first@xabz.com',
billFromAddress: 'Ganesh glory,Godrej garden city,Ahmedabad.',
billFromPhone: 979796786,
billFromFax: 13,
billTo: 'Soft solution.',
billToEmail: "toFirst@agth.com",
billToAddress: 'Godrej garden city,Ahmedabad.',
billToPhone: 757575233,
billToFax: 76,
orders: [{
itemName: 'Courge',
unitPrice: 10,
units: 9,
unitTotalPrice: 90
},
],
orderDate: new Date('2020-10-15'),
totalCost: 90,
vat: 9,
grandTotal: 99,
status: 'Delivered',
completed: false,
isSelected: false
}
];
\ No newline at end of file
import { TestBed } from '@angular/core/testing';
import { InvoiceService } from './invoice.service';
describe('InvoiceService', () => {
let service: InvoiceService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(InvoiceService);
});
// it('should be created', () => {
// expect(service).toBeTruthy();
// });
});
\ No newline at end of file
import { Injectable } from '@angular/core';
import { from } from 'rxjs';
import { InvoiceList } from './invoice';
import { invoceLists } from './invoice-data';
@Injectable()
export class InvoiceService {
private invoiceList: InvoiceList[] = [];
private getInvoice() {
return from(invoceLists);
}
constructor() {
this.getInvoice().subscribe((data) =>
this.invoiceList.push(data)
);
}
public getInvoiceList() {
return this.invoiceList;
}
public deleteInvoice(id: number) {
this.invoiceList = this.invoiceList.filter(CId => CId.id !== id);
}
public addInvoice(invoice: InvoiceList) {
this.invoiceList.splice(0, 0, invoice);
}
public updateInvoice(id: number, invoice: InvoiceList) {
let invoiceDetail = this.getInvoiceList().filter(x => x.id === id)[0];
invoiceDetail = invoice;
}
// public getInvoiceOriginalLst() {
// this.getInvoice().subscribe((data)=>
// this.invoiceLst.push(data)
// );
// return this.invoiceLst;
// }
}
\ No newline at end of file
export class order {
constructor(
public itemName: string = '',
public unitPrice: number = 0,
public units: number = 0,
public unitTotalPrice: number = 0) {
}
}
export class InvoiceList {
constructor(
public id: number = 0,
public billFrom: string = '',
public billFromEmail: string = 'from@mail.com',
public billFromAddress: string = '',
public billFromPhone: number = 758269842,
public billFromFax: number = 0,
public billTo: string = '',
public billToEmail: string = 'to@mail.com',
public billToAddress: string = '',
public billToPhone: number = 58258855,
public billToFax: number = 0,
public orders: order[] = [],
public orderDate: Date = new Date,
public totalCost: number = 0,
public vat: number = 0,
public grandTotal: number = 0,
public status: string = '',
public completed: boolean = false,
public isSelected: boolean = false) {
}
}
\ No newline at end of file
<div class="card mb-0">
<div class="card-body">
<div class="d-md-flex align-items-center">
<div class="form-group mb-0">
<input type="text" placeholder="Search Invoice" class="form-control" [(ngModel)]='searchTerm'>
</div>
<div class="ml-auto mt-4 mt-md-0">
<a routerLink='/apps/addinvoice'>
<button type="button" class="btn btn-info"> <i class="mr-2 mdi mdi-plus"></i> Add Invoice</button>
</a>
</div>
</div>
</div>
</div>
<div class="card pt-3">
<div class="table-responsive">
<table class="table table-borderless table-hover v-middle no-wrap">
<thead>
<tr class="border-bottom">
<th scope="col">
<input type="checkbox" [(ngModel)]="isMasterSel" name="list_name" value="h1"
(change)="checkUncheckAll()" />
</th>
<th scope="col">Id</th>
<th scope="col">Bill From</th>
<th scope="col">Bill To</th>
<th scope="col">Total Cost</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr class="border-bottom "
*ngFor="let invoice of compInvoice|slice: (page-1) * pageSize : (page-1) * pageSize + pageSize; index as i">
<td class="py-4">
<input type="checkbox" [(ngModel)]="invoice.isSelected" name="list_name" value="{{invoice.id}}"
(change)="isAllSelected()" />
</td>
<td class="py-4">{{ invoice.id }} </td>
<td class="py-4">
<ngb-highlight [result]="invoice.billFrom" [term]="searchTerm"></ngb-highlight>
</td>
<td class="py-4">
<ngb-highlight [result]="invoice.billTo" [term]="searchTerm"></ngb-highlight>
</td>
<td class="py-4">
<ngb-highlight [result]="invoice.grandTotal | number" [term]="searchTerm"></ngb-highlight>
</td>
<td class="py-4">
<span class="badge badge-info px-3 font-medium" *ngIf="invoice.status==='Shipped'">
<ngb-highlight [result]="invoice.status" [term]="searchTerm"></ngb-highlight>
</span>
<span class="badge badge-danger px-3 font-medium" *ngIf="invoice.status==='Pending'">
<ngb-highlight [result]="invoice.status" [term]="searchTerm"></ngb-highlight>
</span>
<span class="badge badge-success px-3 font-medium" *ngIf="invoice.status==='Delivered'">
<ngb-highlight [result]="invoice.status" [term]="searchTerm"></ngb-highlight>
</span>
</td>
<td class="py-4">
<!-- <a routerLink='/apps/viewinvoice/'>View</a> -->
<a [routerLink]="['/apps/viewinvoice/',invoice.id]" class="text-info mx-2">
<i-feather name="eye" class="feather-sm"></i-feather>
</a>
<a href="javascript:void(0)" class="text-danger mx-2 pl-3 border-left"
(click)="deleteInvoice(invoice.id)">
<i-feather name="trash-2" class="feather-sm"></i-feather>
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-body">
<div class="d-flex justify-content-center">
<ngb-pagination [(page)]="page" [pageSize]="pageSize" [collectionSize]="totalLengthOfCollection">
</ngb-pagination>
</div>
</div>
</div>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment