@@ -1,6 +1,7 @@ | |||
<div class="subpage"> | |||
<header class="main-header"> | |||
<h2> All Partners <ng-container *ngIf="userData">({{ userData.length }})</ng-container> </h2> | |||
<h2> All Partners <ng-container *ngIf="userData">({{ userData.length }})</ng-container> | |||
</h2> | |||
</header> | |||
<div class="card"> | |||
@@ -11,7 +12,8 @@ | |||
<input type="text" placeholder="Partner name" [(ngModel)]="searchText" (input)="getFilteredData()"> | |||
<label> Search </label> | |||
</div> | |||
<button class="button" (click)="shouldHaveImplementationData = !shouldHaveImplementationData; getFilteredData()"> | |||
<button class="button" | |||
(click)="shouldHaveImplementationData = !shouldHaveImplementationData; getFilteredData()"> | |||
<ng-container *ngIf="!shouldHaveImplementationData"> | |||
Partners with implmentation data | |||
</ng-container> | |||
@@ -19,46 +21,72 @@ | |||
Show all Partners | |||
</ng-container> | |||
</button> | |||
<button class="button" (click)="showExportOptions = true"> <img src="assets/export.svg" alt=""> Export </button> | |||
<button class="button" (click)="showExportOptions = true"> <img src="assets/export.svg" alt=""> Export | |||
</button> | |||
<button class="button"> <img src="assets/filter.svg" alt=""> Filter </button> | |||
</div> | |||
<div class="filter-row"> | |||
<div class="explainer">Filters:</div> | |||
<ng-select [items]="communities" [multiple]="true" [closeOnSelect]="false" bindLabel="name" bindValue="name" | |||
placeholder="Communities" (change)="getFilteredData()" [(ngModel)]="filteredCommunities"> | |||
</ng-select> | |||
<ng-select [items]="countries" [multiple]="true" [closeOnSelect]="false" bindLabel="name" bindValue="name" | |||
placeholder="Countries" (change)="getFilteredData()" [(ngModel)]="filteredCountries"> | |||
</ng-select> | |||
<ng-select *ngIf="filteredCountries.includes('India')" [items]="states" [multiple]="true" | |||
[closeOnSelect]="false" bindLabel="name" bindValue="name" placeholder="States" | |||
(change)="updateDistricts($event)" [(ngModel)]="filteredStates"> | |||
</ng-select> | |||
<ng-select *ngIf="filteredCountries.includes('India') && districts.length > 0" [items]="districts" | |||
[multiple]="true" [closeOnSelect]="false" bindLabel="name" bindValue="name" placeholder="Districts" | |||
(change)="getFilteredData()" [(ngModel)]="filteredDistricts"> | |||
</ng-select> | |||
<ng-select [items]="partnerTypes" [multiple]="true" [closeOnSelect]="false" placeholder="Types" | |||
(change)="getFilteredData()" [(ngModel)]="filteredPartnerTypes"> | |||
</ng-select> | |||
</div> | |||
<ng-container *ngIf="showExportOptions"> | |||
<div class="export-options"> | |||
<div class="sub-options" *ngIf="shouldHaveImplementationData"> | |||
<header> | |||
<h5>Select Data Type</h5> | |||
</header> | |||
</header> | |||
<div> | |||
<span>Profile Data</span> | |||
<div class="radioButton" [ngClass]="{'active' : isProfileData}" (click) = "isProfileData = true; isImplementationData=false; isBothData=false" ></div> | |||
<div class="radioButton" [ngClass]="{'active' : isProfileData}" | |||
(click)="isProfileData = true; isImplementationData=false; isBothData=false"></div> | |||
</div> | |||
<div> | |||
<span>Implementation Data</span> | |||
<div class="radioButton" [ngClass]="{'active' : isImplementationData}" (click) = "isImplementationData= true; isProfileData=false; isBothData=false" ></div> | |||
<div class="radioButton" [ngClass]="{'active' : isImplementationData}" | |||
(click)="isImplementationData= true; isProfileData=false; isBothData=false"></div> | |||
</div> | |||
<div> | |||
<span>Both</span> | |||
<div class="radioButton" [ngClass]="{'active' : isBothData}" (click)="isBothData = true; isProfileData = false; isImplementationData=false"></div> | |||
<div class="radioButton" [ngClass]="{'active' : isBothData}" | |||
(click)="isBothData = true; isProfileData = false; isImplementationData=false"></div> | |||
</div> | |||
</div> | |||
<header> | |||
<h5> Export as </h5> | |||
</header> | |||
<div class="options"> | |||
<button (click) ="exportProfileData('CSV')" class="button"> CSV </button> | |||
<button (click) ="exportProfileData('XLSX')" class="button"> Excel </button> | |||
<div class="options"> | |||
<button (click)="exportProfileData('CSV')" class="button"> CSV </button> | |||
<button (click)="exportProfileData('XLSX')" class="button"> Excel </button> | |||
</div> | |||
</div> | |||
</ng-container> | |||
<section class="table"> | |||
<header> | |||
<div class="col"> <input type="checkbox" [checked]="isAllInputChecked()" (change)="selectAllPartner()"> Select </div> | |||
<div class="col"> <input type="checkbox" [checked]="isAllInputChecked()" (change)="selectAllPartner()"> | |||
Select </div> | |||
<div class="col"> Name </div> | |||
<div class="col"> Primary Disctrict & State </div> | |||
<div class="col"> Type </div> | |||
@@ -68,14 +96,15 @@ | |||
</header> | |||
<section class="data"> | |||
<div class="row" *ngFor="let partner of tempUserData"> | |||
<div class="col"> <input type="checkbox" [checked]="isInputChecked(partner)" (change)="selectPartner(partner)"> </div> | |||
<div class="col"> <input type="checkbox" [checked]="isInputChecked(partner)" | |||
(change)="selectPartner(partner)"> </div> | |||
<div class="col" (click)="showPartnerDetails(partner)"> | |||
{{ partner.organizationBasicInfo.name }} | |||
</div> | |||
<div class="col" (click)="showPartnerDetails(partner)"> | |||
{{ partner.detailedProfile.district }}, {{ partner.detailedProfile.state }} | |||
</div> | |||
<div class="col" (click)="showPartnerDetails(partner)"> | |||
<div class="col" (click)="showPartnerDetails(partner)"> | |||
{{ partner.organizationBasicInfo.type }} | |||
</div> | |||
<div class="col"> | |||
@@ -88,12 +117,13 @@ | |||
<div class="col"> | |||
<div> {{ partner.primaryContact.name }} </div> | |||
<a href="mailTo:{{partner.primaryContact.email}}"> {{ partner.primaryContact.email }} </a> | |||
<a href="tel:{{partner.primaryContact.contactNumber}}"> {{ partner.primaryContact.contactNumber }} </a> | |||
<a href="tel:{{partner.primaryContact.contactNumber}}"> {{ partner.primaryContact.contactNumber | |||
}} </a> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="row" *ngIf="userData.length > tempUserData.length"> | |||
<button class="button" (click)="loadMore()"> Load More </button> | |||
</div> | |||
</div> | |||
</section> | |||
</section> | |||
@@ -27,6 +27,23 @@ | |||
} | |||
} | |||
.filter-row { | |||
padding: 5px 15px; | |||
display: flex; | |||
align-items: center; | |||
.explainer { | |||
flex-basis: 150px; | |||
font-style: italic; | |||
color: silver; | |||
} | |||
ng-select { | |||
flex-grow: 1; | |||
margin: 0 5px; | |||
} | |||
} | |||
.card { | |||
position: relative; | |||
@@ -71,7 +88,7 @@ | |||
.sub-options { | |||
div{ | |||
div { | |||
margin: 3px 0; | |||
display: flex; | |||
align-items: center; | |||
@@ -81,12 +98,12 @@ | |||
color: var(--input-border); | |||
span{ | |||
span { | |||
width: 85%; | |||
} | |||
} | |||
.radioButton{ | |||
.radioButton { | |||
border: 2px solid var(--input-border); | |||
width: 15px; | |||
height: 15px; | |||
@@ -94,7 +111,7 @@ | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
&::before { | |||
content: ''; | |||
display: block; | |||
@@ -103,18 +120,18 @@ | |||
border-radius: inherit; | |||
background-color: white; | |||
} | |||
&.active { | |||
border-color: var(--input-border); | |||
&::before { | |||
background-color: var(--input-border); | |||
} | |||
} | |||
} | |||
} | |||
button { | |||
border: 2px solid var(--input-border); | |||
@@ -126,7 +143,7 @@ | |||
font-weight: 500; | |||
} | |||
} | |||
.table { | |||
@@ -135,13 +152,14 @@ | |||
line-height: 1.8; | |||
letter-spacing: 0.5px; | |||
header, .row { | |||
header, | |||
.row { | |||
display: flex; | |||
flex-wrap: nowrap; | |||
align-items: center; | |||
padding: 0 10px; | |||
.col { | |||
.col { | |||
width: calc(100% / 7); | |||
font-size: 14px; | |||
@@ -149,7 +167,9 @@ | |||
margin-right: 5px; | |||
} | |||
p, a, &>div { | |||
p, | |||
a, | |||
&>div { | |||
display: block; | |||
white-space: nowrap; | |||
overflow: hidden; | |||
@@ -175,7 +195,7 @@ | |||
&:nth-child(5) { | |||
width: 100px; | |||
} | |||
} | |||
} | |||
} | |||
@@ -3,6 +3,9 @@ import { PartnerProfileService } from '../../services/partner-profile.service'; | |||
import { Router } from '@angular/router'; | |||
import * as Papa from 'papaparse'; | |||
import * as XLSX from 'xlsx' | |||
import { UserData, UserDataOption } from 'src/shared/structure/user'; | |||
import { COUNTRIES, STATES, COMMUNITIES } from 'src/shared/data/form-options'; | |||
import { PartnerType, PARTNER_MAPPING } from 'src/shared/data/partner-mapping'; | |||
type exportType = "CSV" | "XLSX"; | |||
@@ -13,16 +16,28 @@ type exportType = "CSV" | "XLSX"; | |||
}) | |||
export class TableComponent implements OnInit { | |||
userData: Array<any> = []; | |||
tempUserData: Array<any> = []; | |||
userData: Array<UserData> = []; | |||
tempUserData: Array<UserData> = []; | |||
showExportOptions: boolean = false; | |||
shouldHaveImplementationData: boolean = false; | |||
searchText: string = ''; | |||
selectedPartnerList: Array<any> = []; | |||
selectedPartnerList: Array<UserData> = []; | |||
isProfileData: boolean = true; | |||
isImplementationData: boolean = false; | |||
isBothData: boolean = false; | |||
communities = COMMUNITIES; | |||
countries = COUNTRIES; | |||
states = STATES; | |||
districts: Array<UserDataOption> = []; | |||
partnerTypes = [PartnerType.ENABLER, PartnerType.IMPLEMENTER, PartnerType.PROVIDER]; | |||
filteredCommunities: Array<string> = []; | |||
filteredCountries: Array<string> = []; | |||
filteredStates: Array<string> = []; | |||
filteredDistricts: Array<string> = []; | |||
filteredPartnerTypes: Array<PartnerType> = []; | |||
exportData: Array<any> = []; | |||
exportSurveyCtoData: Array<any> = []; | |||
@@ -35,33 +50,100 @@ export class TableComponent implements OnInit { | |||
this.getFilteredData(); | |||
} | |||
updateDistricts(states: Array<{ districts: Array<UserDataOption> }>) { | |||
console.log(states); | |||
this.districts = states.map(state => state.districts).flat(); | |||
this.getFilteredData(); | |||
} | |||
getFilteredData() { | |||
this.partnerProfileService.getPartnersData().then((data: any) => { | |||
this.partnerProfileService.getPartnersData().then((data) => { | |||
this.userData = data; | |||
if (this.shouldHaveImplementationData) { | |||
this.userData = this.userData.filter(user => { | |||
return (user.surveyCtoData.hiiData && user.surveyCtoData.hiiData.length > 0) || | |||
const searchText = this.searchText.toLowerCase().trim(); | |||
const filteredCommunitySet = new Set(this.filteredCommunities); | |||
const filteredCountrySet = new Set(this.filteredCountries); | |||
const filteredStateSet = new Set(this.filteredStates); | |||
const filteredDistrictSet = new Set(this.filteredDistricts); | |||
const filteredPartnerTypeSet = new Set(this.filteredPartnerTypes); | |||
this.userData = this.userData.filter(user => { | |||
if (this.shouldHaveImplementationData) { | |||
const hasImplementationData = (user.surveyCtoData.hiiData && user.surveyCtoData.hiiData.length > 0) || | |||
(user.surveyCtoData.spData && user.surveyCtoData.spData.length > 0) || | |||
(user.surveyCtoData.spSchemeData && user.surveyCtoData.spSchemeData.length > 0) | |||
}); | |||
} | |||
if (this.searchText) { | |||
this.userData = this.userData.filter(user => { | |||
return user.organizationBasicInfo.name && user.organizationBasicInfo.name.toLowerCase().trim().includes(this.searchText.toLowerCase().trim()); | |||
}) | |||
} | |||
if (!hasImplementationData) { | |||
return false; | |||
} | |||
} | |||
if (filteredCommunitySet.size > 0) { | |||
const communitiesForUser = user.detailedProfile.communities.map(community => community.name); | |||
const hasCommunities = communitiesForUser.some(community => filteredCommunitySet.has(community)); | |||
if (!hasCommunities) { | |||
return false; | |||
} | |||
} | |||
if (filteredCountrySet.size > 0) { | |||
const countriesForUser = user.detailedProfile.branchLocationCountries.map(country => country.name).concat(user.detailedProfile.partnerLocation); | |||
const hasCountries = countriesForUser.some(country => filteredCountrySet.has(country)); | |||
if (!hasCountries) { | |||
return false; | |||
} | |||
} | |||
if (filteredStateSet.size > 0) { | |||
const statesForUser = user.detailedProfile.states.map(state => state.name).concat(user.detailedProfile.state); | |||
const hasStates = statesForUser.some(state => filteredStateSet.has(state)); | |||
if (!hasStates) { | |||
return false; | |||
} | |||
} | |||
if (filteredDistrictSet.size > 0) { | |||
const districtsForUser = user.detailedProfile.districts.map(district => district.name).concat(user.detailedProfile.district); | |||
const hasDistricts = districtsForUser.some(district => filteredDistrictSet.has(district)); | |||
if (!hasDistricts) { | |||
return false; | |||
} | |||
} | |||
if (filteredPartnerTypeSet.size > 0) { | |||
const partnerTypeOfUser = PARTNER_MAPPING.find(mapping => mapping.portalId === user.portalId)?.type; | |||
const hasPartnerType = partnerTypeOfUser && filteredPartnerTypeSet.has(partnerTypeOfUser); | |||
if (!hasPartnerType) { | |||
return false; | |||
} | |||
} | |||
if (this.searchText) { | |||
const hasSearchText = (!!user.organizationBasicInfo.name && user.organizationBasicInfo.name.toLowerCase().trim().includes(searchText)); | |||
if (!hasSearchText) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
}); | |||
this.partialLoad(this.userData.slice(0, 100)) | |||
console.log(this.userData); | |||
}, (e) => console.log(e)); | |||
} | |||
partialLoad(data: Array<any>) { | |||
partialLoad(data: Array<UserData>) { | |||
this.tempUserData = data; | |||
console.log(this.tempUserData); | |||
} | |||
loadMore() { | |||
@@ -174,9 +256,9 @@ export class TableComponent implements OnInit { | |||
"SP Name": spData.name, | |||
"SP Status": spData.status, | |||
'SP Reason Name': spData.reasonName, | |||
"SP Female Number" : spData.femaleNo ? spData.femaleNo : '' , | |||
"SP Male Number" : spData.maleNo ? spData.maleNo : '', | |||
"Tg Number" : spData.tgNo ? spData.tgNo : '', | |||
"SP Female Number": spData.femaleNo ? spData.femaleNo : '', | |||
"SP Male Number": spData.maleNo ? spData.maleNo : '', | |||
"Tg Number": spData.tgNo ? spData.tgNo : '', | |||
"SP TotalAggregation": spData.totalAggregation, | |||
"SP OtherRemarks": spData.otherRemarks, | |||
"SP RelevantDocuments": spData.relevantDocuments, | |||
@@ -17,7 +17,7 @@ export class PartnerProfileService { | |||
) { } | |||
async getPartnersData() { | |||
return lastValueFrom(this.http.get(BASE_URL + '/user-data/?token=' + localStorage.getItem('token'))); | |||
return lastValueFrom(this.http.get<Array<UserData>>(BASE_URL + '/user-data/?token=' + localStorage.getItem('token'))); | |||
} | |||
async updatePartnerData(userData: UserData) { | |||
@@ -1 +1 @@ | |||
Subproject commit 98e1875b53e2b1612bd350141f86bf38866a5221 | |||
Subproject commit 6e14e2b89a7d2191840dc6a74d1322288e75af30 |