File

src/app/contacts/contacts.component.ts

Implements

OnInit OnDestroy

Metadata

selector crm-contacts
styleUrls contacts.component.scss
templateUrl ./contacts.component.html

Index

Properties
Methods

Constructor

constructor(modalService: NgbModal, contactsService: ContactsService, notificationsService: NotificationsService, formBuilder: FormBuilder, route: ActivatedRoute, confirmDialogService: ConfirmDialogService)
Parameters :
Name Type Optional Description
modalService NgbModal
contactsService ContactsService
notificationsService NotificationsService
formBuilder FormBuilder
route ActivatedRoute
confirmDialogService ConfirmDialogService

Methods

Private addContact
addContact(contact: Contact)
Parameters :
Name Type Optional Description
contact Contact
Returns : void
addGroup
addGroup(group: Group)
Parameters :
Name Type Optional Description
group Group
Returns : void
addSelectedToGroup
addSelectedToGroup(groupId: number)
Parameters :
Name Type Optional Description
groupId number
Returns : void
caretClass
caretClass()
Returns : "fa-caret-down" | "fa-caret-up"
deleteContact
deleteContact(contact: Contact, event: Event)
Parameters :
Name Type Optional Description
contact Contact
event Event
Returns : void
deleteGroup
deleteGroup(id: number)
Parameters :
Name Type Optional Description
id number
Returns : void
Private editContact
editContact(contact: Contact)
Parameters :
Name Type Optional Description
contact Contact
Returns : void
editGroup
editGroup(undefined: )
Parameters :
Name Type Optional Description
Returns : void
filterByGroup
filterByGroup(group: Group)
Parameters :
Name Type Optional Description
group Group
Returns : void
Private filterGroup
filterGroup(text: string)
Parameters :
Name Type Optional Description
text string
Returns : void
isSelected
isSelected(contactId: number)
Parameters :
Name Type Optional Description
contactId number
Returns : boolean
isSomeSelected
isSomeSelected()
Returns : boolean
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onAddToGroup
onAddToGroup()
Returns : void
onDeleteSelectedContacts
onDeleteSelectedContacts()
Returns : void
onRemoveContactFromGroup
onRemoveContactFromGroup(contact: Contact, event: Event)
Parameters :
Name Type Optional Description
contact Contact
event Event
Returns : void
onSelectChange
onSelectChange(event: , contactId: number)
Parameters :
Name Type Optional Description
event
contactId number
Returns : void
openContact
openContact(state: ContactFormState, event: Event, contact?: Contact)
Parameters :
Name Type Optional Description
state ContactFormState
event Event
contact Contact true
Returns : void
Private searchGroupFormInit
searchGroupFormInit()
Returns : void
selectAll
selectAll(event: )
Parameters :
Name Type Optional Description
event
Returns : void
showAll
showAll()
Returns : void
switchGroup
switchGroup()
Returns : void
toggleShowFilter
toggleShowFilter()
Returns : void

Properties

contacts
contacts: Contact[]
Type : Contact[]
Default value : []
contactsBookId
contactsBookId: number
Type : number
contactsFilterData
contactsFilterData:
Default value : new ContactsFilterData()
contactsOwnerEmail
contactsOwnerEmail: string
Type : string
Default value : ''
detailState
detailState:
Default value : ContactFormState.Detail
editState
editState:
Default value : ContactFormState.Edit
filteredGroups
filteredGroups: Group[]
Type : Group[]
Default value : []
groups
groups: Group[]
Type : Group[]
Default value : []
isOwner
isOwner: boolean
Type : boolean
Default value : true
isShowFilters
isShowFilters: boolean
Type : boolean
Default value : false
newState
newState:
Default value : ContactFormState.New
searchGroupForm
searchGroupForm: FormGroup
Type : FormGroup
Private searchGroupSubscription
searchGroupSubscription: Subscription
Type : Subscription
selectedContactsIds
selectedContactsIds: number[]
Type : number[]
Default value : []
selectedGroup
selectedGroup: Group
Type : Group
showGroups
showGroups: boolean
Type : boolean
Default value : false
import {Component, OnInit, OnDestroy} from "@angular/core";
import {NgbModalOptions, NgbModal} from "@ng-bootstrap/ng-bootstrap";
import {ContactsService} from "./contacts.service";
import {NotificationsService} from "../core/notifications/notifications.service";
import {FormGroup, FormBuilder} from "@angular/forms";
import {Subscription} from "rxjs";
import {AddContactsToGroupData, RemoveContactsData, RemoveContactsFromGroupData} from "./contacts.data";
import {ActivatedRoute} from "@angular/router";
import {ContactComponent} from "./shared/contact/contact.component";
import {Contact} from "./shared/contact.model";
import {Group} from "./shared/group.model";
import {ContactFormState} from "./shared/contact/contact-form-state.enum";
import {ContactsBook} from "./shared/contacts-book.model";
import {ConfirmDialogService} from "../core/confirm-dialog/confirm-dialog.service";
import {ContactsFilterData} from "./contacts-filter.pipe";

@Component({
  selector: 'crm-contacts',
  templateUrl: './contacts.component.html',
  styleUrls: ['./contacts.component.scss']
})
export class ContactsComponent implements OnInit, OnDestroy {

  searchGroupForm: FormGroup;
  private searchGroupSubscription: Subscription;

  isOwner: boolean = true;
  contactsOwnerEmail: string = '';

  contacts: Contact[] = [];
  groups: Group[] = [];
  contactsBookId: number;

  selectedContactsIds: number[] = [];
  selectedGroup: Group;
  filteredGroups: Group[] = [];

  newState = ContactFormState.New;
  editState = ContactFormState.Edit;
  detailState = ContactFormState.Detail;

  showGroups: boolean = false;

  contactsFilterData = new ContactsFilterData();

  isShowFilters: boolean = false;

  constructor(private modalService: NgbModal,
              private contactsService: ContactsService,
              private notificationsService: NotificationsService,
              private formBuilder: FormBuilder,
              private route: ActivatedRoute,
              private confirmDialogService: ConfirmDialogService) {
  }

  ngOnInit() {
    this.searchGroupFormInit();

    let getContactsBook;
    if (this.route.snapshot.params.hasOwnProperty('userId')) {
      getContactsBook = this.contactsService.getContactsBookByUserId(+this.route.snapshot.params['userId']);
      this.isOwner = false;
      this.contactsOwnerEmail = this.route.snapshot.queryParams['email'];
    } else {
      getContactsBook = this.contactsService.getContactsBook()
    }

    getContactsBook.subscribe(
      (book: ContactsBook) => {
        this.contacts = book.contacts;
        this.groups = book.groups;
        this.contactsBookId = book.id;
      },
      error => this.notificationsService.error(error.json())
    );

  }

  ngOnDestroy() {
  }

  onSelectChange(event, contactId: number) {
    if (event.target.checked) {
      this.selectedContactsIds.push(contactId)
    } else {
      this.selectedContactsIds.splice(this.selectedContactsIds.indexOf(contactId), 1)
    }
  }

  isSelected(contactId: number): boolean {
    return this.selectedContactsIds.indexOf(contactId) !== -1;
  }

  isSomeSelected() {
    return this.selectedContactsIds.length > 0;
  }

  selectAll(event) {
    if (event.target.checked) {
      this.selectedContactsIds = [];
      this.selectedContactsIds.push(...this.contacts.map(c => c.id));
    } else {
      this.selectedContactsIds = [];
    }
  }

  openContact(state: ContactFormState, event: Event, contact?: Contact) {
    event.stopPropagation();
    const options: NgbModalOptions = {size: 'lg'};
    const modalRef = this.modalService.open(ContactComponent, options);
    modalRef.componentInstance.state = state;
    modalRef.componentInstance.contact = contact;
    modalRef.componentInstance.groups = this.groups;
    modalRef.componentInstance.isOwner = this.isOwner;
    modalRef.componentInstance.newContactEvent.subscribe(contact => this.addContact(contact));
    modalRef.componentInstance.editContactEvent.subscribe(contact => this.editContact(contact));
  }

  deleteContact(contact: Contact, event: Event) {
    event.stopPropagation();
    this.confirmDialogService.ask('You really want delete contact?', 'Delete', 'Delete contact confirmation').then(
      confirm => {
        this.contactsService.deleteContact(contact.id).subscribe(
          ok => {
            this.contacts.splice(this.contacts.indexOf(contact), 1);
            this.notificationsService.success('Contact deleted');
          },
          error => this.notificationsService.error(error.json())
        )
      },
      cancel => console.debug('Cancel')
    );
  }

  private addContact(contact: Contact) {
    this.contacts.push(contact);
  }

  private editContact(contact: Contact) {
    let oldContact = this.contacts.find(c => c.id === contact.id);
    this.contacts[this.contacts.indexOf(oldContact)] = contact;
  }

  switchGroup() {
    this.showGroups = !this.showGroups
  }

  addGroup(group: Group) {
    this.groups.push(group)
  }

  editGroup({id, name}) {
    this.groups.forEach((item) => {
      if (item.id === id) {
        item.name = name;
        return;
      }
    });
  }

  deleteGroup(id: number) {
    this.groups.forEach((item, index, arr) => {
      if (item.id === id) {
        arr.splice(index, 1);
        return;
      }
    });
  }

  private searchGroupFormInit() {
    this.searchGroupForm = this.formBuilder.group({
      group: ['']
    });

    this.searchGroupSubscription = this.searchGroupForm.valueChanges.debounceTime(200).subscribe(formValue => {
      this.filterGroup(formValue.group)
    });
  }

  onDeleteSelectedContacts() {
    this.confirmDialogService.ask('You really want delete contacts?', 'Delete', 'Delete contacts confirmation').then(
      confirm => {
        this.contactsService.deleteContacts(new RemoveContactsData(this.selectedContactsIds)).subscribe(
          ok => {
            this.selectedContactsIds.forEach(id => {
              let contact = this.contacts.find(c => c.id === id);
              this.contacts.splice(this.contacts.indexOf(contact), 1);
            });
            this.selectedContactsIds = [];
            this.notificationsService.success('Contacts deleted');
          },
          error => {
            this.notificationsService.error(error.json())
          }
        );
      },
      cancel => console.debug('cancel')
    )
  }

  onAddToGroup() {
    this.searchGroupFormInit();
    this.filteredGroups = [];
    this.filteredGroups.push(...this.groups.slice(0, 10))
  }

  private filterGroup(text: string) {
    this.filteredGroups = [];
    this.filteredGroups.push(...this.groups.filter(group => group.name.toLowerCase().startsWith(text.toLowerCase())).slice(0, 10))
  }

  addSelectedToGroup(groupId: number) {
    this.contactsService.addContactsToGroup(new AddContactsToGroupData(groupId, this.selectedContactsIds)).subscribe(
      ok => {
        const group = this.groups.find(g => g.id === groupId);
        this.contacts.forEach(contact => {
          if (this.selectedContactsIds.indexOf(contact.id) !== -1) {
            contact.groups.push(group);
          }
        });
        this.selectedContactsIds = [];
        this.notificationsService.success('Contacts added to group');
      },
      error => {
        this.notificationsService.error(error.json())
      }
    )
  }

  filterByGroup(group: Group) {
    this.selectedGroup = group;
    this.contactsFilterData.filterByGroup(group.id)
  }

  showAll() {
    this.selectedGroup = null;
    this.contactsFilterData.cleanGroupFilter();
  }

  onRemoveContactFromGroup(contact: Contact, event: Event) {
    event.stopPropagation();
    this.contactsService.deleteContactFromGroup(new RemoveContactsFromGroupData(this.selectedGroup.id, [contact.id])).subscribe(
      ok => {
        this.contacts[this.contacts.indexOf(contact)].groups.splice(contact.groups.indexOf(this.selectedGroup), 1);
        this.notificationsService.success('Contact removed from group');
      },
      error => {
        this.notificationsService.error(error.json())
      }
    )
  }

  caretClass() {
    return this.contactsFilterData.orderASC ? 'fa-caret-down' : 'fa-caret-up'
  }

  toggleShowFilter() {
    this.contactsFilterData.cleanSearchFields();
    this.isShowFilters = !this.isShowFilters
  }

}
<div class="animated fadeIn">
  <div class="row">
    <div class="col-sm-12" [class.col-md-9]="showGroups">
      <div class="card">
        <div class="card-block">
          <div class="row margin-row-bottom">
            <div class="col-sm-4">
              <h4 class="card-title mb-0">Contacts <span *ngIf="!isOwner">({{contactsOwnerEmail}})</span></h4>
            </div>
            <div class="col-sm-8">
              <div class="pull-right">
                <div class="btn-group" *ngIf="isSomeSelected() && isOwner" crmDropdown>

                  <button class="btn btn-link text-muted" title="Add to group" (click)="onAddToGroup()">
                    <span class="fa fa-group fa-lg"></span>
                  </button>

                  <div class="dropdown-menu dropdown-menu-right groups-search-dropdown">

                    <form [formGroup]="searchGroupForm" class="form-horizontal">
                      <input type="text"
                             class="form-control"
                             placeholder="Start typing group name..."
                             formControlName="group">
                    </form>

                    <button class="dropdown-item btn btn-link"
                            *ngFor="let group of filteredGroups"
                            (click)="addSelectedToGroup(group.id)">{{group.name}}
                    </button>
                  </div>
                </div>

                <button class="btn btn-link text-muted" title="Delete selected contacts"
                        (click)="onDeleteSelectedContacts()" *ngIf="isSomeSelected() && isOwner">
                  <span class="fa fa-trash fa-lg"></span>
                </button>

                <button type="button" class="btn btn-primary" (click)="openContact(newState, $event)" *ngIf="isOwner"><i
                  class="icon-plus"></i> Add contact
                </button>

                <button type="button" class="btn btn-default" *ngIf="!showGroups" (click)="switchGroup()">Groups <span
                  class="icon-arrow-left"></span></button>
                <button type="button" class="btn btn-default" *ngIf="showGroups" (click)="switchGroup()">Groups <span
                  class="icon-arrow-right"></span></button>
              </div>
            </div>
          </div>
          <div class="text-primary" *ngIf="!!selectedGroup">
            <div class="h5 text-primary m-b-0 m-t-h">
              Group "{{selectedGroup.name}}"
              <button class="btn btn-default" (click)="showAll()">Show all contacts</button>
            </div>

          </div>
          <table class="table table-hover table-outline m-b-0 hidden-sm-down">
            <thead class="thead-default">
            <tr>
              <th width="12">
                <input type="checkbox" id="all" class="form-control th-input" name="allContacts"
                       (change)="selectAll($event)" [checked]="isSomeSelected()">
              </th>
              <th>
                <a (click)="contactsFilterData.orderById()" class="cursor-pointer"> Id
                  <span *ngIf="contactsFilterData.isOrderedById()"
                        class="fa" [ngClass]="caretClass()">
                  </span>
                </a>
              </th>
              <th>
                <a (click)="contactsFilterData.orderByName()" class="cursor-pointer"> Name
                  <span *ngIf="contactsFilterData.isOrderedByName()"
                        class="fa" [ngClass]="caretClass()">
                  </span>
                </a>
              </th>
              <th>
                <a (click)="contactsFilterData.orderByCompany()" class="cursor-pointer"> Company
                  <span *ngIf="contactsFilterData.isOrderedByCompany()"
                        class="fa" [ngClass]="caretClass()">

                  </span>
                </a>
              </th>
              <th>
                Phone
              </th>
              <th>
                Email
              </th>
              <th width="140" class="text-right">
                <button class="btn btn-link text-muted action-padding" title="Filter contacts" (click)="toggleShowFilter()">
                  <span class="fa fa-filter fa-lg"></span>
                </button>
              </th>
            </tr>
            </thead>
            <tbody>

            <tr *ngIf="isShowFilters">
              <th class="th-padding">
              </th>
              <th class="th-padding" width="50">
                <input type="number" class="form-control" [(ngModel)]="contactsFilterData.id" title="id" placeholder="Id">
              </th>
              <th class="th-padding">
                <input type="text" class="form-control" [(ngModel)]="contactsFilterData.name" title="name" placeholder="Name">
              </th>
              <th class="th-padding">
                <input type="text" class="form-control" [(ngModel)]="contactsFilterData.company" title="company" placeholder="Company">
              </th>
              <th class="th-padding">
                <input type="text" class="form-control" [(ngModel)]="contactsFilterData.phone" title="phone" placeholder="Phone">
              </th>
              <th class="th-padding">
                <input type="text" class="form-control" [(ngModel)]="contactsFilterData.email" title="email" placeholder="Email">
              </th>
              <th width="140" class="th-padding"></th>
            </tr>

            <tr *ngFor="let contact of contacts | contactsFilter : contactsFilterData"
                (click)="openContact(detailState, $event, contact)"
                title="Click for detail">

              <td (click)="$event.stopPropagation()">
                <input type="checkbox"
                       id="{{contact.id}}"
                       name="contacts"
                       value="{{contact.id}}"
                       (change)="onSelectChange($event, contact.id)"
                       [checked]="isSelected(contact.id)">
              </td>

              <td>{{contact.id}}</td>
              <td><a>{{contact.name}}</a></td>
              <td class="text-centred">{{contact.company}}</td>
              <td class="text-centred">{{contact.phones[0]?.phone}}</td>
              <td class="text-centred">{{contact.emails[0]?.email}}</td>
              <td class="text-right">
                <button class="btn btn-link text-muted action-padding" title="Edit contact"
                        (click)="openContact(editState, $event, contact)" *ngIf="isOwner">
                  <span class="fa fa-pencil fa-lg"></span>
                </button>
                <button class="btn btn-link text-muted action-padding" title="Delete contact"
                        (click)="deleteContact(contact, $event)" *ngIf="isOwner">
                  <span class="fa fa-trash fa-lg"></span>
                </button>
                <button class="btn btn-link text-muted action-padding" title="Delete from group"
                        (click)="onRemoveContactFromGroup(contact, $event)" *ngIf="!!selectedGroup && isOwner">
                  <span class="fa fa-close fa-lg"></span>
                </button>
              </td>
            </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
    <div class="col-sm-12" [class.col-md-3]="showGroups" *ngIf="showGroups">
      <crm-contact-groups [groups]="groups"
                          [contactsBookId]="contactsBookId"
                          [isOwner]="isOwner"
                          (newGroupEvent)="addGroup($event)"
                          (editGroupEvent)="editGroup($event)"
                          (deleteGroupEvent)="deleteGroup($event)"
                          (filterEvent)="filterByGroup($event)">
      </crm-contact-groups>
    </div>
  </div>
</div>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""