feat: add product management features and integrate role selection

- Added PRODUCTS_ROUTES to app routing.
- Removed roles.const.ts and related references to central-auth-roles.
- Updated login component to remove role selection logic.
- Integrated ToastService for success notifications in customer, inventory, product brand, product category, supplier, and user forms.
- Implemented product and category selection fields in product form.
- Created reusable select components for product brands and categories.
- Enhanced user form with password validation and role selection.
- Established roles service for fetching roles from the API.
This commit is contained in:
2025-12-06 11:09:06 +03:30
parent 0419ff2fc7
commit 70f39de9d8
47 changed files with 436 additions and 90 deletions
@@ -0,0 +1,2 @@
export * from './select.component';
export * from './tag.component';
@@ -0,0 +1,12 @@
<uikit-field label="نقش" name="role" [control]="control">
<p-select
[options]="roles()"
[id]="'role'"
[optionValue]="'id'"
optionLabel="name"
[attr.name]="'role'"
[formControl]="control"
[loading]="loading()"
[invalid]="control.invalid && (control.dirty || control.touched)"
></p-select>
</uikit-field>
@@ -0,0 +1,38 @@
import { Maybe } from '@/core';
import { UikitFieldComponent } from '@/uikit';
import { Component, Input, signal } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { Select } from 'primeng/select';
import { IRoleResponse } from '../models';
import { RolesService } from '../services';
@Component({
selector: 'catalog-roles-select',
templateUrl: './select.component.html',
imports: [UikitFieldComponent, Select, ReactiveFormsModule],
})
export class CatalogRolesComponent {
@Input() control!: FormControl<Maybe<number>>;
constructor(private service: RolesService) {
this.getData();
}
roles = signal<IRoleResponse[]>([]);
loading = signal<boolean>(false);
private getData() {
this.loading.set(true);
return this.service.getAll().subscribe({
next: (res) => {
this.roles.set(res);
},
error: () => {
this.roles.set([]);
},
complete: () => {
this.loading.set(false);
},
});
}
}
@@ -0,0 +1 @@
{{ roleTitle() }}
@@ -0,0 +1,16 @@
import { Component, Input } from '@angular/core';
import { IRoleResponse } from '../models';
@Component({
selector: 'catalog-role-tag',
templateUrl: './tag.component.html',
})
export class CatalogRoleTagComponent {
@Input() role!: IRoleResponse;
constructor() {}
roleTitle() {
return this.role.name;
}
}
@@ -0,0 +1,5 @@
const baseUrl = '/api/v1/roles';
export const ROLES_API_ROUTES = {
list: () => `${baseUrl}`,
};
@@ -0,0 +1 @@
export * from './apiRoutes';
+4
View File
@@ -0,0 +1,4 @@
export * from './components';
export * from './constants';
export * from './models';
export * from './services';
@@ -0,0 +1 @@
export * from './io';
@@ -0,0 +1,6 @@
export interface IRoleRawResponse {
id: number;
name: string;
description: string;
}
export interface IRoleResponse extends IRoleRawResponse {}
@@ -0,0 +1 @@
export * from './main.service';
@@ -0,0 +1,19 @@
import { IPaginatedResponse } from '@/core/models/service.model';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';
import { ROLES_API_ROUTES } from '../constants';
import { IRoleRawResponse, IRoleResponse } from '../models';
@Injectable({ providedIn: 'root' })
export class RolesService {
constructor(private http: HttpClient) {}
private apiRoutes = ROLES_API_ROUTES;
getAll(): Observable<IRoleResponse[]> {
return this.http
.get<IPaginatedResponse<IRoleRawResponse>>(this.apiRoutes.list())
.pipe(map((response) => response.data as IRoleResponse[]));
}
}