@duyanhdev/mvp-ifs-ui-kit 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/.editorconfig +16 -0
  2. package/.gitmodules +3 -0
  3. package/.postcssrc.json +5 -0
  4. package/.prettierignore +14 -0
  5. package/.prettierrc.json +29 -0
  6. package/LICENSE.md +21 -0
  7. package/README.md +59 -0
  8. package/angular.json +98 -0
  9. package/eslint.config.js +89 -0
  10. package/package.json +59 -0
  11. package/public/demo/images/flag/flag_placeholder.png +0 -0
  12. package/public/demo/images/footer-image.gif +0 -0
  13. package/public/demo/images/galleria/galleria1.jpg +0 -0
  14. package/public/demo/images/galleria/galleria10.jpg +0 -0
  15. package/public/demo/images/galleria/galleria10s.jpg +0 -0
  16. package/public/demo/images/galleria/galleria11.jpg +0 -0
  17. package/public/demo/images/galleria/galleria11s.jpg +0 -0
  18. package/public/demo/images/galleria/galleria12.jpg +0 -0
  19. package/public/demo/images/galleria/galleria12s.jpg +0 -0
  20. package/public/demo/images/galleria/galleria13.jpg +0 -0
  21. package/public/demo/images/galleria/galleria13s.jpg +0 -0
  22. package/public/demo/images/galleria/galleria14.jpg +0 -0
  23. package/public/demo/images/galleria/galleria14s.jpg +0 -0
  24. package/public/demo/images/galleria/galleria15.jpg +0 -0
  25. package/public/demo/images/galleria/galleria15s.jpg +0 -0
  26. package/public/demo/images/galleria/galleria1s.jpg +0 -0
  27. package/public/demo/images/galleria/galleria2.jpg +0 -0
  28. package/public/demo/images/galleria/galleria2s.jpg +0 -0
  29. package/public/demo/images/galleria/galleria3.jpg +0 -0
  30. package/public/demo/images/galleria/galleria3s.jpg +0 -0
  31. package/public/demo/images/galleria/galleria4.jpg +0 -0
  32. package/public/demo/images/galleria/galleria4s.jpg +0 -0
  33. package/public/demo/images/galleria/galleria5.jpg +0 -0
  34. package/public/demo/images/galleria/galleria5s.jpg +0 -0
  35. package/public/demo/images/galleria/galleria6.jpg +0 -0
  36. package/public/demo/images/galleria/galleria6s.jpg +0 -0
  37. package/public/demo/images/galleria/galleria7.jpg +0 -0
  38. package/public/demo/images/galleria/galleria7s.jpg +0 -0
  39. package/public/demo/images/galleria/galleria8.jpg +0 -0
  40. package/public/demo/images/galleria/galleria8s.jpg +0 -0
  41. package/public/demo/images/galleria/galleria9.jpg +0 -0
  42. package/public/demo/images/galleria/galleria9s.jpg +0 -0
  43. package/public/demo/images/product/bamboo-watch.jpg +0 -0
  44. package/public/demo/images/product/black-watch.jpg +0 -0
  45. package/public/demo/images/product/blue-band.jpg +0 -0
  46. package/public/demo/images/product/blue-t-shirt.jpg +0 -0
  47. package/public/demo/images/product/bracelet.jpg +0 -0
  48. package/public/demo/images/product/brown-purse.jpg +0 -0
  49. package/public/demo/images/product/chakra-bracelet.jpg +0 -0
  50. package/public/demo/images/product/galaxy-earrings.jpg +0 -0
  51. package/public/demo/images/product/game-controller.jpg +0 -0
  52. package/public/demo/images/product/gaming-set.jpg +0 -0
  53. package/public/demo/images/product/gold-phone-case.jpg +0 -0
  54. package/public/demo/images/product/green-earbuds.jpg +0 -0
  55. package/public/demo/images/product/green-t-shirt.jpg +0 -0
  56. package/public/demo/images/product/grey-t-shirt.jpg +0 -0
  57. package/public/demo/images/product/headphones.jpg +0 -0
  58. package/public/demo/images/product/light-green-t-shirt.jpg +0 -0
  59. package/public/demo/images/product/lime-band.jpg +0 -0
  60. package/public/demo/images/product/mini-speakers.jpg +0 -0
  61. package/public/demo/images/product/painted-phone-case.jpg +0 -0
  62. package/public/demo/images/product/pink-band.jpg +0 -0
  63. package/public/demo/images/product/pink-purse.jpg +0 -0
  64. package/public/demo/images/product/product-placeholder.svg +10 -0
  65. package/public/demo/images/product/purple-band.jpg +0 -0
  66. package/public/demo/images/product/purple-gemstone-necklace.jpg +0 -0
  67. package/public/demo/images/product/purple-t-shirt.jpg +0 -0
  68. package/public/demo/images/product/shoes.jpg +0 -0
  69. package/public/demo/images/product/sneakers.jpg +0 -0
  70. package/public/demo/images/product/teal-t-shirt.jpg +0 -0
  71. package/public/demo/images/product/yellow-earbuds.jpg +0 -0
  72. package/public/demo/images/product/yoga-mat.jpg +0 -0
  73. package/public/demo/images/product/yoga-set.jpg +0 -0
  74. package/src/app/layout/component/configurator/app.configurator.html +48 -0
  75. package/src/app/layout/component/configurator/app.configurator.ts +396 -0
  76. package/src/app/layout/component/floatingconfigurator/app.floatingconfigurator.ts +31 -0
  77. package/src/app/layout/component/footer/app.footer.scss +52 -0
  78. package/src/app/layout/component/footer/app.footer.ts +26 -0
  79. package/src/app/layout/component/layout/app.layout.ts +50 -0
  80. package/src/app/layout/component/menu/app.menu.html +7 -0
  81. package/src/app/layout/component/menu/app.menu.scss +13 -0
  82. package/src/app/layout/component/menu/app.menu.ts +90 -0
  83. package/src/app/layout/component/menuitem/app.menuitem.html +56 -0
  84. package/src/app/layout/component/menuitem/app.menuitem.scss +218 -0
  85. package/src/app/layout/component/menuitem/app.menuitem.ts +126 -0
  86. package/src/app/layout/component/sidebar/app.sidebar.html +3 -0
  87. package/src/app/layout/component/sidebar/app.sidebar.scss +0 -0
  88. package/src/app/layout/component/sidebar/app.sidebar.ts +106 -0
  89. package/src/app/layout/component/topbar/app.topbar.html +190 -0
  90. package/src/app/layout/component/topbar/app.topbar.scss +8 -0
  91. package/src/app/layout/component/topbar/app.topbar.ts +68 -0
  92. package/src/app/layout/service/layout.service.ts +117 -0
  93. package/src/app/pages/auth/access.ts +32 -0
  94. package/src/app/pages/auth/auth.routes.ts +10 -0
  95. package/src/app/pages/auth/error.ts +32 -0
  96. package/src/app/pages/auth/login.ts +71 -0
  97. package/src/app/pages/crud/crud.ts +387 -0
  98. package/src/app/pages/dashboard/dashboard.css +778 -0
  99. package/src/app/pages/dashboard/dashboard.html +191 -0
  100. package/src/app/pages/dashboard/dashboard.ts +348 -0
  101. package/src/app/pages/documentation/documentation.ts +73 -0
  102. package/src/app/pages/empty/empty.ts +11 -0
  103. package/src/app/pages/landing/components/featureswidget.ts +139 -0
  104. package/src/app/pages/landing/components/footerwidget.ts +73 -0
  105. package/src/app/pages/landing/components/herowidget.ts +25 -0
  106. package/src/app/pages/landing/components/highlightswidget.ts +46 -0
  107. package/src/app/pages/landing/components/pricingwidget.ts +119 -0
  108. package/src/app/pages/landing/components/topbarwidget.component.ts +68 -0
  109. package/src/app/pages/landing/landing.ts +31 -0
  110. package/src/app/pages/notfound/notfound.ts +68 -0
  111. package/src/app/pages/pages.routes.ts +17 -0
  112. package/src/app/pages/profile/profile.html +57 -0
  113. package/src/app/pages/profile/profile.scss +145 -0
  114. package/src/app/pages/profile/profile.ts +19 -0
  115. package/src/app/pages/service/country.service.ts +255 -0
  116. package/src/app/pages/service/customer.service.ts +9057 -0
  117. package/src/app/pages/service/icon.service.ts +23 -0
  118. package/src/app/pages/service/node.service.ts +816 -0
  119. package/src/app/pages/service/photo.service.ts +103 -0
  120. package/src/app/pages/service/product.service.ts +1322 -0
  121. package/src/app/pages/tickets/tickets-create/tickets-create.html +140 -0
  122. package/src/app/pages/tickets/tickets-create/tickets-create.scss +617 -0
  123. package/src/app/pages/tickets/tickets-create/tickets-create.ts +104 -0
  124. package/src/app/pages/tickets/tickets-list/ticket-list.html +150 -0
  125. package/src/app/pages/tickets/tickets-list/ticket-list.scss +392 -0
  126. package/src/app/pages/tickets/tickets-list/ticket-list.ts +178 -0
  127. package/src/app/pages/uikit/buttondemo.ts +254 -0
  128. package/src/app/pages/uikit/chartdemo.ts +290 -0
  129. package/src/app/pages/uikit/filedemo.ts +52 -0
  130. package/src/app/pages/uikit/formlayoutdemo.ts +129 -0
  131. package/src/app/pages/uikit/inputdemo.ts +339 -0
  132. package/src/app/pages/uikit/listdemo.ts +217 -0
  133. package/src/app/pages/uikit/mediademo.ts +1021 -0
  134. package/src/app/pages/uikit/menudemo.ts +540 -0
  135. package/src/app/pages/uikit/messagesdemo.ts +101 -0
  136. package/src/app/pages/uikit/miscdemo.ts +192 -0
  137. package/src/app/pages/uikit/overlaydemo.ts +235 -0
  138. package/src/app/pages/uikit/panelsdemo.ts +235 -0
  139. package/src/app/pages/uikit/tabledemo.ts +568 -0
  140. package/src/app/pages/uikit/timelinedemo.ts +141 -0
  141. package/src/app/pages/uikit/treedemo.ts +75 -0
  142. package/src/app/pages/uikit/uikit.routes.ts +35 -0
  143. package/src/app.component.ts +22 -0
  144. package/src/app.config.ts +23 -0
  145. package/src/app.routes.ts +23 -0
  146. package/src/assets/demo/code.scss +17 -0
  147. package/src/assets/demo/demo.scss +2 -0
  148. package/src/assets/demo/flags/flags.css +984 -0
  149. package/src/assets/layout/_core.scss +24 -0
  150. package/src/assets/layout/_footer.scss +8 -0
  151. package/src/assets/layout/_main.scss +21 -0
  152. package/src/assets/layout/_menu.scss +159 -0
  153. package/src/assets/layout/_mixins.scss +15 -0
  154. package/src/assets/layout/_preloading.scss +47 -0
  155. package/src/assets/layout/_responsive.scss +111 -0
  156. package/src/assets/layout/_topbar.scss +201 -0
  157. package/src/assets/layout/_typography.scss +68 -0
  158. package/src/assets/layout/_utils.scss +25 -0
  159. package/src/assets/layout/layout.scss +13 -0
  160. package/src/assets/layout/variables/_common.scss +21 -0
  161. package/src/assets/layout/variables/_dark.scss +5 -0
  162. package/src/assets/layout/variables/_light.scss +5 -0
  163. package/src/assets/styles.scss +4 -0
  164. package/src/assets/tailwind.css +32 -0
  165. package/src/index.html +15 -0
  166. package/src/main.ts +5 -0
  167. package/tsconfig.app.json +15 -0
  168. package/tsconfig.json +33 -0
  169. package/tsconfig.spec.json +15 -0
  170. package/vercel.json +9 -0
@@ -0,0 +1,387 @@
1
+ import { Component, OnInit, signal, ViewChild } from '@angular/core';
2
+ import { ConfirmationService, MessageService } from 'primeng/api';
3
+ import { Table, TableModule } from 'primeng/table';
4
+ import { CommonModule } from '@angular/common';
5
+ import { FormsModule } from '@angular/forms';
6
+ import { ButtonModule } from 'primeng/button';
7
+ import { RippleModule } from 'primeng/ripple';
8
+ import { ToastModule } from 'primeng/toast';
9
+ import { ToolbarModule } from 'primeng/toolbar';
10
+ import { RatingModule } from 'primeng/rating';
11
+ import { InputTextModule } from 'primeng/inputtext';
12
+ import { TextareaModule } from 'primeng/textarea';
13
+ import { SelectModule } from 'primeng/select';
14
+ import { RadioButtonModule } from 'primeng/radiobutton';
15
+ import { InputNumberModule } from 'primeng/inputnumber';
16
+ import { DialogModule } from 'primeng/dialog';
17
+ import { TagModule } from 'primeng/tag';
18
+ import { InputIconModule } from 'primeng/inputicon';
19
+ import { IconFieldModule } from 'primeng/iconfield';
20
+ import { ConfirmDialogModule } from 'primeng/confirmdialog';
21
+ import { Product, ProductService } from '@/app/pages/service/product.service';
22
+
23
+ interface Column {
24
+ field: string;
25
+ header: string;
26
+ customExportHeader?: string;
27
+ }
28
+
29
+ interface ExportColumn {
30
+ title: string;
31
+ dataKey: string;
32
+ }
33
+
34
+ @Component({
35
+ selector: 'app-crud',
36
+ standalone: true,
37
+ imports: [
38
+ CommonModule,
39
+ TableModule,
40
+ FormsModule,
41
+ ButtonModule,
42
+ RippleModule,
43
+ ToastModule,
44
+ ToolbarModule,
45
+ RatingModule,
46
+ InputTextModule,
47
+ TextareaModule,
48
+ SelectModule,
49
+ RadioButtonModule,
50
+ InputNumberModule,
51
+ DialogModule,
52
+ TagModule,
53
+ InputIconModule,
54
+ IconFieldModule,
55
+ ConfirmDialogModule
56
+ ],
57
+ template: `
58
+ <p-toolbar styleClass="mb-6">
59
+ <ng-template #start>
60
+ <p-button label="New" icon="pi pi-plus" severity="secondary" class="mr-2" (onClick)="openNew()" />
61
+ <p-button severity="secondary" label="Delete" icon="pi pi-trash" outlined (onClick)="deleteSelectedProducts()" [disabled]="!selectedProducts || !selectedProducts.length" />
62
+ </ng-template>
63
+
64
+ <ng-template #end>
65
+ <p-button label="Export" icon="pi pi-upload" severity="secondary" (onClick)="exportCSV()" />
66
+ </ng-template>
67
+ </p-toolbar>
68
+
69
+ <p-table
70
+ #dt
71
+ [value]="products()"
72
+ [rows]="10"
73
+ [columns]="cols"
74
+ [paginator]="true"
75
+ [globalFilterFields]="['name', 'country.name', 'representative.name', 'status']"
76
+ [tableStyle]="{ 'min-width': '75rem' }"
77
+ [(selection)]="selectedProducts"
78
+ [rowHover]="true"
79
+ dataKey="id"
80
+ currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products"
81
+ [showCurrentPageReport]="true"
82
+ [rowsPerPageOptions]="[10, 20, 30]"
83
+ >
84
+ <ng-template #caption>
85
+ <div class="flex items-center justify-between">
86
+ <h5 class="m-0">Manage Products</h5>
87
+ <p-iconfield>
88
+ <p-inputicon styleClass="pi pi-search" />
89
+ <input pInputText type="text" (input)="onGlobalFilter(dt, $event)" placeholder="Search..." />
90
+ </p-iconfield>
91
+ </div>
92
+ </ng-template>
93
+ <ng-template #header>
94
+ <tr>
95
+ <th style="width: 3rem">
96
+ <p-tableHeaderCheckbox />
97
+ </th>
98
+ <th style="min-width: 16rem">Code</th>
99
+ <th pSortableColumn="name" style="min-width:16rem">
100
+ Name
101
+ <p-sortIcon field="name" />
102
+ </th>
103
+ <th>Image</th>
104
+ <th pSortableColumn="price" style="min-width: 8rem">
105
+ Price
106
+ <p-sortIcon field="price" />
107
+ </th>
108
+ <th pSortableColumn="category" style="min-width:10rem">
109
+ Category
110
+ <p-sortIcon field="category" />
111
+ </th>
112
+ <th pSortableColumn="rating" style="min-width: 12rem">
113
+ Reviews
114
+ <p-sortIcon field="rating" />
115
+ </th>
116
+ <th pSortableColumn="inventoryStatus" style="min-width: 12rem">
117
+ Status
118
+ <p-sortIcon field="inventoryStatus" />
119
+ </th>
120
+ <th style="min-width: 12rem"></th>
121
+ </tr>
122
+ </ng-template>
123
+ <ng-template #body let-product>
124
+ <tr>
125
+ <td style="width: 3rem">
126
+ <p-tableCheckbox [value]="product" />
127
+ </td>
128
+ <td style="min-width: 12rem">{{ product.code }}</td>
129
+ <td style="min-width: 16rem">{{ product.name }}</td>
130
+ <td>
131
+ <img [src]="'https://primefaces.org/cdn/primeng/images/demo/product/' + product.image" [alt]="product.name" style="width: 64px" class="rounded" />
132
+ </td>
133
+ <td>{{ product.price | currency: 'USD' }}</td>
134
+ <td>{{ product.category }}</td>
135
+ <td>
136
+ <p-rating [(ngModel)]="product.rating" [readonly]="true" />
137
+ </td>
138
+ <td>
139
+ <p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product.inventoryStatus)" />
140
+ </td>
141
+ <td>
142
+ <p-button icon="pi pi-pencil" class="mr-2" [rounded]="true" [outlined]="true" (click)="editProduct(product)" />
143
+ <p-button icon="pi pi-trash" severity="danger" [rounded]="true" [outlined]="true" (click)="deleteProduct(product)" />
144
+ </td>
145
+ </tr>
146
+ </ng-template>
147
+ </p-table>
148
+
149
+ <p-dialog [(visible)]="productDialog" [style]="{ width: '450px' }" header="Product Details" [modal]="true">
150
+ <ng-template #content>
151
+ <div class="flex flex-col gap-6">
152
+ <img [src]="'https://primefaces.org/cdn/primeng/images/demo/product/' + product.image" [alt]="product.image" class="block m-auto pb-4" *ngIf="product.image" />
153
+ <div>
154
+ <label for="name" class="block font-bold mb-3">Name</label>
155
+ <input type="text" pInputText id="name" [(ngModel)]="product.name" required autofocus fluid />
156
+ <small class="text-red-500" *ngIf="submitted && !product.name">Name is required.</small>
157
+ </div>
158
+ <div>
159
+ <label for="description" class="block font-bold mb-3">Description</label>
160
+ <textarea id="description" pTextarea [(ngModel)]="product.description" required rows="3" cols="20" fluid></textarea>
161
+ </div>
162
+
163
+ <div>
164
+ <label for="inventoryStatus" class="block font-bold mb-3">Inventory Status</label>
165
+ <p-select [(ngModel)]="product.inventoryStatus" inputId="inventoryStatus" [options]="statuses" optionLabel="label" optionValue="label" placeholder="Select a Status" fluid />
166
+ </div>
167
+
168
+ <div>
169
+ <span class="block font-bold mb-4">Category</span>
170
+ <div class="grid grid-cols-12 gap-4">
171
+ <div class="flex items-center gap-2 col-span-6">
172
+ <p-radiobutton id="category1" name="category" value="Accessories" [(ngModel)]="product.category" />
173
+ <label for="category1">Accessories</label>
174
+ </div>
175
+ <div class="flex items-center gap-2 col-span-6">
176
+ <p-radiobutton id="category2" name="category" value="Clothing" [(ngModel)]="product.category" />
177
+ <label for="category2">Clothing</label>
178
+ </div>
179
+ <div class="flex items-center gap-2 col-span-6">
180
+ <p-radiobutton id="category3" name="category" value="Electronics" [(ngModel)]="product.category" />
181
+ <label for="category3">Electronics</label>
182
+ </div>
183
+ <div class="flex items-center gap-2 col-span-6">
184
+ <p-radiobutton id="category4" name="category" value="Fitness" [(ngModel)]="product.category" />
185
+ <label for="category4">Fitness</label>
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ <div class="grid grid-cols-12 gap-4">
191
+ <div class="col-span-6">
192
+ <label for="price" class="block font-bold mb-3">Price</label>
193
+ <p-inputnumber id="price" [(ngModel)]="product.price" mode="currency" currency="USD" locale="en-US" fluid />
194
+ </div>
195
+ <div class="col-span-6">
196
+ <label for="quantity" class="block font-bold mb-3">Quantity</label>
197
+ <p-inputnumber id="quantity" [(ngModel)]="product.quantity" fluid />
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </ng-template>
202
+
203
+ <ng-template #footer>
204
+ <p-button label="Cancel" icon="pi pi-times" text (click)="hideDialog()" />
205
+ <p-button label="Save" icon="pi pi-check" (click)="saveProduct()" />
206
+ </ng-template>
207
+ </p-dialog>
208
+
209
+ <p-confirmdialog [style]="{ width: '450px' }" />
210
+ `,
211
+ providers: [MessageService, ProductService, ConfirmationService]
212
+ })
213
+ export class Crud implements OnInit {
214
+ productDialog: boolean = false;
215
+
216
+ products = signal<Product[]>([]);
217
+
218
+ product!: Product;
219
+
220
+ selectedProducts!: Product[] | null;
221
+
222
+ submitted: boolean = false;
223
+
224
+ statuses!: any[];
225
+
226
+ @ViewChild('dt') dt!: Table;
227
+
228
+ exportColumns!: ExportColumn[];
229
+
230
+ cols!: Column[];
231
+
232
+ constructor(
233
+ private productService: ProductService,
234
+ private messageService: MessageService,
235
+ private confirmationService: ConfirmationService
236
+ ) {}
237
+
238
+ exportCSV() {
239
+ this.dt.exportCSV();
240
+ }
241
+
242
+ ngOnInit() {
243
+ this.loadDemoData();
244
+ }
245
+
246
+ loadDemoData() {
247
+ this.productService.getProducts().then((data) => {
248
+ this.products.set(data);
249
+ });
250
+
251
+ this.statuses = [
252
+ { label: 'INSTOCK', value: 'instock' },
253
+ { label: 'LOWSTOCK', value: 'lowstock' },
254
+ { label: 'OUTOFSTOCK', value: 'outofstock' }
255
+ ];
256
+
257
+ this.cols = [
258
+ { field: 'code', header: 'Code', customExportHeader: 'Product Code' },
259
+ { field: 'name', header: 'Name' },
260
+ { field: 'image', header: 'Image' },
261
+ { field: 'price', header: 'Price' },
262
+ { field: 'category', header: 'Category' }
263
+ ];
264
+
265
+ this.exportColumns = this.cols.map((col) => ({ title: col.header, dataKey: col.field }));
266
+ }
267
+
268
+ onGlobalFilter(table: Table, event: Event) {
269
+ table.filterGlobal((event.target as HTMLInputElement).value, 'contains');
270
+ }
271
+
272
+ openNew() {
273
+ this.product = {};
274
+ this.submitted = false;
275
+ this.productDialog = true;
276
+ }
277
+
278
+ editProduct(product: Product) {
279
+ this.product = { ...product };
280
+ this.productDialog = true;
281
+ }
282
+
283
+ deleteSelectedProducts() {
284
+ this.confirmationService.confirm({
285
+ message: 'Are you sure you want to delete the selected products?',
286
+ header: 'Confirm',
287
+ icon: 'pi pi-exclamation-triangle',
288
+ accept: () => {
289
+ this.products.set(this.products().filter((val) => !this.selectedProducts?.includes(val)));
290
+ this.selectedProducts = null;
291
+ this.messageService.add({
292
+ severity: 'success',
293
+ summary: 'Successful',
294
+ detail: 'Products Deleted',
295
+ life: 3000
296
+ });
297
+ }
298
+ });
299
+ }
300
+
301
+ hideDialog() {
302
+ this.productDialog = false;
303
+ this.submitted = false;
304
+ }
305
+
306
+ deleteProduct(product: Product) {
307
+ this.confirmationService.confirm({
308
+ message: 'Are you sure you want to delete ' + product.name + '?',
309
+ header: 'Confirm',
310
+ icon: 'pi pi-exclamation-triangle',
311
+ accept: () => {
312
+ this.products.set(this.products().filter((val) => val.id !== product.id));
313
+ this.product = {};
314
+ this.messageService.add({
315
+ severity: 'success',
316
+ summary: 'Successful',
317
+ detail: 'Product Deleted',
318
+ life: 3000
319
+ });
320
+ }
321
+ });
322
+ }
323
+
324
+ findIndexById(id: string): number {
325
+ let index = -1;
326
+ for (let i = 0; i < this.products().length; i++) {
327
+ if (this.products()[i].id === id) {
328
+ index = i;
329
+ break;
330
+ }
331
+ }
332
+
333
+ return index;
334
+ }
335
+
336
+ createId(): string {
337
+ let id = '';
338
+ var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
339
+ for (var i = 0; i < 5; i++) {
340
+ id += chars.charAt(Math.floor(Math.random() * chars.length));
341
+ }
342
+ return id;
343
+ }
344
+
345
+ getSeverity(status: string) {
346
+ switch (status) {
347
+ case 'INSTOCK':
348
+ return 'success';
349
+ case 'LOWSTOCK':
350
+ return 'warn';
351
+ case 'OUTOFSTOCK':
352
+ return 'danger';
353
+ default:
354
+ return 'info';
355
+ }
356
+ }
357
+
358
+ saveProduct() {
359
+ this.submitted = true;
360
+ let _products = this.products();
361
+ if (this.product.name?.trim()) {
362
+ if (this.product.id) {
363
+ _products[this.findIndexById(this.product.id)] = this.product;
364
+ this.products.set([..._products]);
365
+ this.messageService.add({
366
+ severity: 'success',
367
+ summary: 'Successful',
368
+ detail: 'Product Updated',
369
+ life: 3000
370
+ });
371
+ } else {
372
+ this.product.id = this.createId();
373
+ this.product.image = 'product-placeholder.svg';
374
+ this.messageService.add({
375
+ severity: 'success',
376
+ summary: 'Successful',
377
+ detail: 'Product Created',
378
+ life: 3000
379
+ });
380
+ this.products.set([..._products, this.product]);
381
+ }
382
+
383
+ this.productDialog = false;
384
+ this.product = {};
385
+ }
386
+ }
387
+ }