feat: Add Cardex module with filters and invoices components

- Implemented Cardex routes and integrated with the main application routing.
- Created filters component for Cardex to filter inventory and product data.
- Developed invoices component to display supplier invoices with detailed views.
- Enhanced Products module with pagination and state management using a store.
- Updated Suppliers module to include invoice management and detailed supplier views.
- Refactored state management in Products and Suppliers to utilize signals for reactive updates.
- Added new models and services to support the Cardex functionality.
- Improved UI components for better user experience in displaying data.
This commit is contained in:
2025-12-21 19:09:13 +03:30
parent 108d192f88
commit e937c994d7
29 changed files with 716 additions and 49 deletions
+16 -10
View File
@@ -1,6 +1,7 @@
import { Signal, WritableSignal, computed, signal } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { Maybe } from '../models';
import { IPaginatedQuery, IResponseMetadata } from '../models/service.model';
/**
* Base interface for all state objects
@@ -8,9 +9,10 @@ import { Maybe } from '../models';
export interface BaseState<T = any> {
loading: boolean;
error: Maybe<string>;
lastId?: string;
currentPage?: number;
items?: T;
meta?: Record<string, any>;
meta?: Maybe<IPaginatedQuery>;
isRefreshing?: boolean;
}
/**
@@ -21,6 +23,7 @@ export interface PaginatedState<T = any> extends BaseState {
totalCount: number;
currentPage: number;
pageSize: number;
totalPages: number;
hasMore: boolean;
}
@@ -246,21 +249,24 @@ export abstract class PaginatedStore<
readonly currentPage = computed(() => this._state().currentPage);
readonly pageSize = computed(() => this._state().pageSize);
readonly hasMore = computed(() => this._state().hasMore);
readonly totalPages = computed(() => {
const state = this._state();
return Math.ceil(state.totalCount / state.pageSize);
});
readonly totalPages = computed(() => this._state().totalPages);
readonly paginatedMeta = computed(() => ({
currentPage: this.currentPage(),
totalPages: this.totalPages(),
totalCount: this.totalCount(),
pageSize: this.pageSize(),
}));
/**
* Set items for current page
*/
protected setItems(items: T[], totalCount: number, currentPage: number): void {
protected setItems(items: T[], meta: IResponseMetadata): void {
const state = this._state();
this.patchState({
items,
totalCount,
currentPage,
hasMore: currentPage * state.pageSize < totalCount,
totalCount: meta.totalRecords,
currentPage: meta.page,
hasMore: meta.page < meta.totalPages,
loading: false,
error: null,
} as Partial<TState>);