agmission/Development/client/src/app/customers/customer-list/customer-list.component.ts

186 lines
6.4 KiB
TypeScript

import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SelectItem } from 'primeng/api';
import { Table } from 'primeng/table';
import { Customer } from '../models/customer.model';
import * as fromCustomers from '../reducers';
import * as customerActions from '../actions/customer.actions';
import { globals, OperationalStatus } from '@app/shared/global';
import { BaseComp } from '@app/shared/base/base.component';
import { CustomerCacheService } from '@app/domain/services/customer-cache.service';
import { ListReturnCacheService } from '@app/domain/services/list-return-cache.service';
import { FilterDefinition, FilterChangeEvent } from '@app/shared/dynamic-filter/dynamic-filter.component';
@Component({
selector: 'agm-customer-list',
templateUrl: './customer-list.component.html',
styleUrls: ['./customer-list.component.css']
})
export class CustomerListComponent extends BaseComp implements OnInit, OnDestroy {
readonly CREATED = 'createdAt';
readonly ACTIVE = OperationalStatus.ACTIVE;
readonly BILLABLE = 'billable';
readonly PARTNER = 'partner';
readonly PARTNER_NAME = 'partnerName';
customers: Array<Customer>;
curCust: Customer;
@ViewChild("dt") dt: Table;
statuses: SelectItem[];
partners: SelectItem[];
cols: any[];
totalItems;
isSelfSignup = false;
searchAccordionOpen = sessionStorage.getItem('customers-list-accordion') === 'true';
private lastFiltersQuery: Record<string, any> | undefined;
private useCacheOnReturn = false;
cacheTtlSeconds: number;
customerFilterDefinitions: FilterDefinition[];
constructor(
private readonly route: ActivatedRoute,
private readonly customerCache: CustomerCacheService,
private readonly listReturnCache: ListReturnCacheService,
) {
super();
this.cacheTtlSeconds = Math.round(this.customerCache.getTtlMs() / 1000);
this.totalItems = { '=0': '', '=1': '1 ' + $localize`:@@customer:customer`.toLocaleLowerCase(), 'other': $localize`:@@total#Customers:Total: # customers` };
this.statuses = [
{ label: globals.all, value: null },
{ label: globals.active, value: true },
{ label: globals.notActive, value: false }
];
this.cols = [
{ field: "name", header: globals.name, filtered: true, filterMatchMode: 'contains' },
{ field: "username", header: globals.userName, filtered: true, filterMatchMode: 'contains' },
{ field: "contact", header: globals.contact },
{ field: "totalJobs", header: globals.jobs, width: '5%', filtered: false },
{ field: this.CREATED, header: globals.from, width: '6%' },
{ field: this.BILLABLE, header: "Billable", width: '9%' },
{ field: this.ACTIVE, header: globals.active, width: '9%' },
{ field: this.PARTNER_NAME, header: globals.partner, width: '9%' }
];
this.customerFilterDefinitions = [
{ key: 'name', label: globals.name, dataType: 'text' },
{ key: 'username', label: globals.userName, dataType: 'text' },
{ key: 'email', label: globals.email, dataType: 'text' },
{ key: 'contact', label: globals.contact, dataType: 'text' },
{ key: 'createdAt', label: globals.from, dataType: 'date-preset' },
];
}
ngOnInit() {
const saved = localStorage.getItem('isSelfSignup');
this.isSelfSignup = saved === 'true';
this.sub$ = this.store.select(fromCustomers.getAllCustomers).subscribe(customers => {
this.setCustomersAndPartners(customers);
});
this.sub$.add(this.store.select(fromCustomers.getSelectedCustomer).subscribe(cust => {
this.curCust = cust;
}));
this.useCacheOnReturn = this.listReturnCache.startVisit('customers');
const savedFilters = sessionStorage.getItem('customers-list-last-filters');
if (savedFilters) {
try {
this.lastFiltersQuery = JSON.parse(savedFilters);
} catch (_err) {
this.lastFiltersQuery = undefined;
}
}
this.store.dispatch(savedFilters
? new customerActions.Fetch({ filters: savedFilters, useCache: this.useCacheOnReturn })
: new customerActions.Fetch({ useCache: this.useCacheOnReturn })
);
}
private setCustomersAndPartners(customers: Customer[]) {
const filtered = this.isSelfSignup ? customers.filter(c => c.selfSignup) : customers;
this.customers = filtered.map(c => ({
...c,
partnerName: c.partner?.name || null
}));
this.partners = [
{ label: globals.all, value: null },
...customers
.filter(c => c.partner)
.map(c => c.partner.name)
.filter((v, i, a) => a.indexOf(v) === i)
.map(name => ({ label: name, value: name }))
];
}
onToggle(event: any): void {
this.isSelfSignup = event.checked;
localStorage.setItem('isSelfSignup', String(this.isSelfSignup));
this.store.select(fromCustomers.getAllCustomers).subscribe(customers => {
this.setCustomersAndPartners(customers);
});
}
onRowSelect(event) {
this.store.dispatch(new customerActions.Select(event.data));
}
onAccordionToggle(expanded: boolean) {
sessionStorage.setItem('customers-list-accordion', String(expanded));
}
updateCacheTtl(): void {
const ttlMs = this.customerCache.setTtlMs(Number(this.cacheTtlSeconds || 0) * 1000);
this.cacheTtlSeconds = Math.round(ttlMs / 1000);
}
onFiltersSubmit(event: FilterChangeEvent) {
const q = { ...event.query };
const filtersStr = JSON.stringify(q);
const prevFilters = sessionStorage.getItem('customers-list-last-filters');
if (filtersStr !== prevFilters) {
this.customerCache.invalidate();
this.useCacheOnReturn = false;
}
this.lastFiltersQuery = q;
sessionStorage.setItem('customers-list-last-filters', filtersStr);
this.store.dispatch(new customerActions.Fetch({ filters: filtersStr, useCache: this.useCacheOnReturn }));
}
get canEdit() {
return (this.curCust && this.curCust._id !== '0');
}
newCustomer() {
this.router.navigate(['customer', '0'], { relativeTo: this.route });
}
editCustomer() {
this.listReturnCache.markPending('customers');
this.router.navigate(['customer', this.curCust._id], { relativeTo: this.route });
}
deleteCustomer() {
if (!this.curCust) { return; }
this.confirmSvc.confirm({
message: globals.confirmDeleteThing.replace('#thing#', globals.customer),
accept: () => {
this.store.dispatch(new customerActions.Delete(this.curCust));
this.curCust = null;
}
});
}
ngOnDestroy() {
super.ngOnDestroy();
}
}