This commit is contained in:
2026-05-21 21:33:37 +05:30
parent f50dd4692d
commit 26478608b1
28 changed files with 4948 additions and 259 deletions

View File

@@ -0,0 +1,322 @@
<div class="card">
<p-toast />
<p-toolbar class="mb-6">
<ng-template #start>
<p-button label="New Subsidiary" icon="pi pi-plus" class="mr-2" (onClick)="openNew()" />
</ng-template>
<ng-template #end>
<p-button label="Export" icon="pi pi-upload" severity="secondary" (onClick)="exportCSV()" styleClass="mx-2" />
<p-button label="Refresh" icon="pi pi-refresh" severity="info" (onClick)="loadAllSubsidiaries()" />
</ng-template>
</p-toolbar>
<p-table
#dt
[value]="isLoading ? skeletonData : subsidiaries"
[rows]="5"
[columns]="cols"
[paginator]="true"
[globalFilterFields]="['name', 'code']"
[tableStyle]="{ 'min-width': '75rem' }"
[(selection)]="selectedSubsidiaries"
[rowHover]="true"
dataKey="id"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
[showCurrentPageReport]="true"
>
<ng-template #caption>
<div class="flex justify-content-between align-items-center">
<h4 class="m-0">Manage Subsidiaries</h4>
<p-iconfield>
<p-inputicon class="pi pi-search" />
<input pInputText type="text" (input)="onSearch($event)" placeholder="Search..." />
</p-iconfield>
</div>
</ng-template>
<ng-template #header>
<tr>
<th style="width: 3rem">#</th>
<th style="min-width: 5rem">Code</th>
<th pSortableColumn="name">
<div class="flex items-center gap-2">
Name
<p-sortIcon field="name" />
</div>
</th>
<th pSortableColumn="emailId" style="min-width: 10rem">
<div class="flex items-center gap-2">
Email
<p-sortIcon field="emailId" />
</div>
</th>
<th pSortableColumn="updatedAt" style="width: 13rem">
<div class="flex items-center gap-2">
Updated At
<p-sortIcon field="updatedAt" />
</div>
</th>
<th pSortableColumn="updatedUser" style="min-width: 12rem">
<div class="flex items-center gap-2">
Updated By
<p-sortIcon field="updatedUser" />
</div>
</th>
<th pSortableColumn="active" style="width: 4rem">
<div class="flex items-center gap-2">
Status
<p-sortIcon field="active" />
</div>
</th>
<th style="min-width: 8rem"></th>
</tr>
</ng-template>
<ng-template #body let-subsidiary let-rowIndex="rowIndex">
<tr *ngIf="!isLoading">
<td>{{ rowIndex + 1 }}</td>
<td style="width: 5rem">{{ subsidiary.code }}</td>
<td>{{ subsidiary.name }}</td>
<td>
<span *ngIf="subsidiary.emailId; else noEmail">
{{ subsidiary.emailId }}
</span>
<ng-template #noEmail>
<em class="text-500 ">Not Available</em>
</ng-template>
</td>
<td>{{ subsidiary.updatedAt | date:'dd/MM/yyyy HH:mm:ss' }}</td>
<td>
<span *ngIf="subsidiary.updatedUser; else noUpdatedUser">
{{ subsidiary.updatedUser }}
</span>
<ng-template #noUpdatedUser>
<em class="text-500 ">Not Available</em>
</ng-template>
</td>
<td>
<p-tag [value]="subsidiary.active ? 'Active' : 'Inactive'" [severity]="getSeverity(subsidiary.active)" />
</td>
<td>
<p-button icon="pi pi-pencil" class="mr-2" [rounded]="true" [outlined]="true" (click)="editSubsidiary(subsidiary)" />
<p-button [icon]="subsidiary.active ? 'pi pi-ban' : 'pi pi-check'" [severity]="subsidiary.active ? 'danger' : 'success'" [rounded]="true" [outlined]="true" (click)="toggleActive(subsidiary)" />
</td>
</tr>
<tr *ngIf="isLoading">
<td><p-skeleton width="2rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="4rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="10rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="8rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="10rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="8rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="4rem" height="1.5rem"></p-skeleton></td>
<td><p-skeleton width="2rem" height="1.5rem"></p-skeleton></td>
</tr>
</ng-template>
</p-table>
<p-dialog [(visible)]="subsidiaryDialog" [style]="{'width': '50vw'}" [breakpoints]="{ '960px': '75vw', '640px': '90vw' }" header="Subsidiary Details" [modal]="true">
<ng-template #content>
<form [formGroup]="subsidiaryForm" (ngSubmit)="saveSubsidiary()" class="mt-2">
<div class="grid mt-0">
<div class="col-12 md:col-3">
<p-floatlabel variant="on">
<input
id="code"
pInputText
formControlName="code"
fluid
[class.p-invalid]="isFieldInvalid('code')"
pTooltip="{{ getErrorMessage('code') }}"
tooltipPosition="top"
autofocus
/>
<label for="code">Code <span class="text-red-500">*</span></label>
</p-floatlabel>
</div>
<div class="col-12 md:col-9">
<p-floatlabel variant="on">
<input
id="name"
pInputText
formControlName="name"
fluid
[class.p-invalid]="isFieldInvalid('name')"
pTooltip="{{ getErrorMessage('name') }}"
tooltipPosition="top"
/>
<label for="name">Subsidiary Name <span class="text-red-500">*</span></label>
</p-floatlabel>
</div>
<div class="col-12 md:col-12">
<p-floatlabel variant="on">
<input
id="officeNo"
pInputText
formControlName="officeNo"
fluid
/>
<label for="officeNo">Office No., Floor, Building</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-6">
<p-floatlabel variant="on">
<input
id="street"
pInputText
formControlName="street"
fluid
/>
<label for="street">Street</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-6">
<p-floatlabel variant="on">
<input
id="locality"
pInputText
formControlName="locality"
fluid
/>
<label for="locality">Locality</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<p-autoComplete
id="cityName"
formControlName="cityName"
[suggestions]="suggestions"
optionLabel="display"
[scrollHeight]="'160px'"
appendTo="body"
(completeMethod)="searchCities($event)"
(onSelect)="onSelectCity($event)"
fluid
/>
<label for="cityName">City</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="stateName"
pInputText
formControlName="stateName"
fluid
/>
<label for="stateName">State</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="pinCode"
pInputText
formControlName="pinCode"
fluid
[class.p-invalid]="isFieldInvalid('pinCode')"
pTooltip="{{ getErrorMessage('pinCode') }}"
tooltipPosition="top"
/>
<label for="pinCode">Pincode</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="emailId"
pInputText
formControlName="emailId"
fluid
[class.p-invalid]="isFieldInvalid('emailId')"
pTooltip="{{ getErrorMessage('emailId') }}"
tooltipPosition="top"
/>
<label for="emailId">Email ID</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="contactNo"
pInputText
formControlName="contactNo"
fluid
[class.p-invalid]="isFieldInvalid('contactNo')"
pTooltip="{{ getErrorMessage('contactNo') }}"
tooltipPosition="top"
/>
<label for="contactNo">Contact No.</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="contactPerson"
pInputText
formControlName="contactPerson"
fluid
[class.p-invalid]="isFieldInvalid('contactPerson')"
pTooltip="{{ getErrorMessage('contactPerson') }}"
tooltipPosition="top"
/>
<label for="contactPerson">Contact Person</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="panNo"
pInputText
formControlName="panNo"
fluid
[class.p-invalid]="isFieldInvalid('panNo')"
pTooltip="{{ getErrorMessage('panNo') }}"
tooltipPosition="top"
/>
<label for="panNo">PAN No.</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="cinNo"
pInputText
formControlName="cinNo"
fluid
[class.p-invalid]="isFieldInvalid('cinNo')"
pTooltip="{{ getErrorMessage('cinNo') }}"
tooltipPosition="top"
/>
<label for="cinNo">CIN No.</label>
</p-floatlabel>
</div>
<div class="col-12 md:col-4">
<p-floatlabel variant="on">
<input
id="msmeNo"
pInputText
formControlName="msmeNo"
fluid
[class.p-invalid]="isFieldInvalid('msmeNo')"
pTooltip="{{ getErrorMessage('msmeNo') }}"
tooltipPosition="top"
/>
<label for="msmeNo">MSME No.</label>
</p-floatlabel>
</div>
</div>
</form>
</ng-template>
<ng-template #footer>
<p-button label="Cancel" icon="pi pi-times" text (click)="hideDialog()" />
<p-button label="Save" icon="pi pi-check" (click)="saveSubsidiary()" />
</ng-template>
</p-dialog>
<p-confirmDialog [style]="{ width: '450px' }" />
</div>