292 lines
14 KiB
HTML
292 lines
14 KiB
HTML
<div class="contacts-container">
|
|
<div class="actions-bar">
|
|
<mat-slide-toggle (change)="toggleShowInactiveContacts()">
|
|
Show Inactive Contacts
|
|
</mat-slide-toggle>
|
|
|
|
<button mat-raised-button color="primary" (click)="addNewContact()">
|
|
<mat-icon>add</mat-icon> Add New Contact
|
|
</button>
|
|
</div>
|
|
|
|
<div class="table-container mat-elevation-z8">
|
|
<div class="loading-shade" *ngIf="isLoading">
|
|
<mat-spinner diameter="50"></mat-spinner>
|
|
</div>
|
|
|
|
<table mat-table [dataSource]="dataSource" matSort>
|
|
<!-- First Name Column -->
|
|
<ng-container matColumnDef="firstName">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>First Name</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.firstName }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Middle Initial Column -->
|
|
<ng-container matColumnDef="middleInitial">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Middle Initial</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.middleInitial }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Last Name Column -->
|
|
<ng-container matColumnDef="lastName">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Last Name</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.lastName }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Title Column -->
|
|
<ng-container matColumnDef="title">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Title</th>
|
|
<td mat-cell *matCellDef="let contact">{{ getContactTitleLabel(contact.title) }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Phone Column -->
|
|
<ng-container matColumnDef="phone">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Phone</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.phone | phone }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Mobile Column -->
|
|
<ng-container matColumnDef="mobile">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Mobile</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.mobile | phone }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Fax Column -->
|
|
<ng-container matColumnDef="fax">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Fax</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.fax }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Email Column -->
|
|
<ng-container matColumnDef="email">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Email</th>
|
|
<td mat-cell *matCellDef="let contact">{{ contact.email }}</td>
|
|
</ng-container>
|
|
|
|
<!-- Default Contact Column -->
|
|
<ng-container matColumnDef="defaultContact">
|
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Default</th>
|
|
<td mat-cell *matCellDef="let contact">
|
|
<mat-icon [color]="contact.defaultContact ? 'primary' : ''">
|
|
{{ contact.defaultContact ? 'star' : 'star_border' }}
|
|
</mat-icon>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<!-- Actions Column -->
|
|
<ng-container matColumnDef="actions">
|
|
<th mat-header-cell *matHeaderCellDef>Actions</th>
|
|
<td mat-cell *matCellDef="let contact">
|
|
<button mat-icon-button color="primary" (click)="editContact(contact)" matTooltip="Edit">
|
|
<mat-icon>edit</mat-icon>
|
|
</button>
|
|
<button mat-icon-button color="primary" *ngIf="!contact.isInactive || !contact.hasLogin"
|
|
[hidden]="contact.isInactive || contact.hasLogin" (click)="createLogin(contact.clientContactId)"
|
|
matTooltip="Login">
|
|
<mat-icon>person</mat-icon>
|
|
</button>
|
|
<button mat-icon-button color="warn" *ngIf="!contact.defaultContact || !contact.isInactive" (click)="
|
|
inactivateContact(contact.clientContactId)"
|
|
[hidden]="contact.defaultContact || contact.isInactive" matTooltip="Inactivate">
|
|
<mat-icon>delete</mat-icon>
|
|
</button>
|
|
<button mat-icon-button color="warn" *ngIf="contact.isInactive" (click)="
|
|
reactivateContact(contact.clientContactId)" [hidden]="!contact.isInactive" matTooltip="Reactivate">
|
|
<mat-icon>loupe</mat-icon>
|
|
</button>
|
|
<button mat-icon-button (click)="setDefaultContact(contact.clientContactId)"
|
|
*ngIf="!contact.defaultContact || !contact.isInactive"
|
|
[hidden]="contact.defaultContact || contact.isInactive" matTooltip="Set as default contact">
|
|
<mat-icon>star</mat-icon>
|
|
</button>
|
|
</td>
|
|
</ng-container>
|
|
|
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
|
|
|
<tr matNoDataRow *matNoDataRow>
|
|
<td [colSpan]="displayedColumns.length" class="no-data-message">
|
|
<mat-icon>info</mat-icon>
|
|
<span>No records available</span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<mat-paginator *ngIf="dataSource.data.length > userPreferences.pageSize!" [length]="dataSource.data.length"
|
|
[pageSizeOptions]="[userPreferences.pageSize!]" [hidePageSize]="true" showFirstLastButtons></mat-paginator>
|
|
</div>
|
|
|
|
<!-- Contact Form -->
|
|
<div class="form-container" *ngIf="showForm">
|
|
<form [formGroup]="contactForm" (ngSubmit)="saveContact()">
|
|
<div class="form-header">
|
|
<h3>{{ isEditing ? 'Edit Contact' : 'Add New Contact' }}</h3>
|
|
</div>
|
|
|
|
<div class="form-row" *ngIf="!isEditing">
|
|
<mat-form-field appearance="outline" class="location">
|
|
<mat-label>Location</mat-label>
|
|
<mat-select formControlName="locationid" required>
|
|
<mat-option *ngFor="let location of locations" [value]="location.locationid">
|
|
{{ getLocationLabel(location) }}
|
|
</mat-option>
|
|
</mat-select>
|
|
<mat-error *ngIf="contactForm.get('locationid')?.errors?.['required']">
|
|
Location is required
|
|
</mat-error>
|
|
</mat-form-field>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>First Name</mat-label>
|
|
<input matInput formControlName="firstName" required>
|
|
<mat-icon matSuffix>person</mat-icon>
|
|
<mat-error *ngIf="contactForm.get('firstName')?.errors?.['required']">
|
|
First name is required
|
|
</mat-error>
|
|
<mat-error *ngIf="contactForm.get('firstName')?.errors?.['maxlength']">
|
|
Maximum 50 characters allowed
|
|
</mat-error>
|
|
</mat-form-field>
|
|
|
|
<mat-form-field appearance="outline" class="small-field">
|
|
<mat-label>Middle Initial</mat-label>
|
|
<input matInput formControlName="middleInitial" maxlength="1">
|
|
<mat-error *ngIf="contactForm.get('middleInitial')?.errors?.['maxlength']">
|
|
Only 1 character allowed
|
|
</mat-error>
|
|
</mat-form-field>
|
|
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>Last Name</mat-label>
|
|
<input matInput formControlName="lastName" required>
|
|
<mat-icon matSuffix>person</mat-icon>
|
|
<mat-error *ngIf="contactForm.get('lastName')?.errors?.['required']">
|
|
Last name is required
|
|
</mat-error>
|
|
<mat-error *ngIf="contactForm.get('lastName')?.errors?.['maxlength']">
|
|
Maximum 50 characters allowed
|
|
</mat-error>
|
|
</mat-form-field>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>Title</mat-label>
|
|
<mat-select formControlName="title" required>
|
|
<mat-option *ngFor="let contactTitle of contactTitles" [value]="contactTitle.value">
|
|
{{ contactTitle.name }}
|
|
</mat-option>
|
|
</mat-select>
|
|
<mat-error *ngIf="contactForm.get('title')?.errors?.['required']">
|
|
Title is required
|
|
</mat-error>
|
|
</mat-form-field>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>Phone</mat-label>
|
|
<input matInput formControlName="phone" required>
|
|
<mat-icon matSuffix>phone</mat-icon>
|
|
<mat-error *ngIf="contactForm.get('phone')?.errors?.['required']">
|
|
Phone is required
|
|
</mat-error>
|
|
<mat-error *ngIf="contactForm.get('phone')?.errors?.['pattern']">
|
|
Please enter a valid phone number (10-15 digits)
|
|
</mat-error>
|
|
</mat-form-field>
|
|
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>Mobile</mat-label>
|
|
<input matInput formControlName="mobile">
|
|
<mat-icon matSuffix>smartphone</mat-icon>
|
|
<mat-error *ngIf="contactForm.get('mobile')?.errors?.['required']">
|
|
Mobile is required
|
|
</mat-error>
|
|
<mat-error *ngIf="contactForm.get('mobile')?.errors?.['pattern']">
|
|
Please enter a valid mobile number (10-15 digits)
|
|
</mat-error>
|
|
</mat-form-field>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>Fax</mat-label>
|
|
<input matInput formControlName="fax">
|
|
<mat-icon matSuffix>fax</mat-icon>
|
|
<mat-error *ngIf="contactForm.get('fax')?.errors?.['pattern']">
|
|
Please enter a valid fax number (10-15 digits)
|
|
</mat-error>
|
|
</mat-form-field>
|
|
|
|
<mat-form-field appearance="outline">
|
|
<mat-label>Email</mat-label>
|
|
<input matInput formControlName="email" required>
|
|
<mat-icon matSuffix>email</mat-icon>
|
|
<mat-error *ngIf="contactForm.get('email')?.errors?.['required']">
|
|
Email is required
|
|
</mat-error>
|
|
<mat-error *ngIf="contactForm.get('email')?.errors?.['email']">
|
|
Please enter a valid email address
|
|
</mat-error>
|
|
<mat-error *ngIf="contactForm.get('email')?.errors?.['maxlength']">
|
|
Maximum 100 characters allowed
|
|
</mat-error>
|
|
</mat-form-field>
|
|
</div>
|
|
<!--
|
|
<div class="form-row">
|
|
<mat-checkbox formControlName="defaultContact">Default Contact</mat-checkbox>
|
|
</div> -->
|
|
<div *ngIf="isEditing" class="readonly-section top-divider">
|
|
<div class="readonly-fields">
|
|
<div class="field-column">
|
|
<!-- Last Changed By -->
|
|
<div class="readonly-field">
|
|
<label>Last Changed By</label>
|
|
<div class="readonly-value">
|
|
{{contactReadOnlyFields.lastChangedBy || 'N/A'}}
|
|
</div>
|
|
</div>
|
|
<!-- Inactive status -->
|
|
<div class="readonly-field">
|
|
<label>Inactive Status </label>
|
|
<div class="readonly-value">
|
|
{{contactReadOnlyFields.isInactive === true ? 'Yes' : 'No' }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="field-column">
|
|
|
|
<!-- Last Changed Date -->
|
|
<div class="readonly-field">
|
|
<label>Last Changed Date</label>
|
|
<div class="readonly-value">
|
|
{{(contactReadOnlyFields.lastChangedDate | date:'mediumDate':'UTC') || 'N/A'}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Inactivated Date -->
|
|
<div class="readonly-field">
|
|
<label>Inactivated Date</label>
|
|
<div class="readonly-value">
|
|
{{(contactReadOnlyFields.inactivatedDate | date:'mediumDate':'UTC') || 'N/A'}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button mat-raised-button color="primary" type="submit"
|
|
[disabled]="contactForm.invalid || changeInProgress">
|
|
{{ isEditing ? 'Update' : 'Save' }}
|
|
</button>
|
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div> |