@cbm-common/relationship-movements-modal
v0.0.2
Published
Componente modal de Angular para visualizar movimientos bancarios relacionados con operaciones específicas en el sistema CBM. Implementa un modal interactivo con animaciones personalizadas y integración completa con el ecosistema de librerías CBM.
Readme
Relationship Movements Modal
Componente modal de Angular para visualizar movimientos bancarios relacionados con operaciones específicas en el sistema CBM. Implementa un modal interactivo con animaciones personalizadas y integración completa con el ecosistema de librerías CBM.
📦 Instalación
npm install @cbm-common/relationship-movements-modal⚙️ Configuración
Importación del Componente
El componente es standalone, por lo que se puede importar directamente:
import { CbmRelationshipMovementsComponent } from '@cbm-common/relationship-movements-modal';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [CbmRelationshipMovementsComponent],
template: `
<cbm-relationship-movements
[isOpen]="showModal"
[bankId]="selectedBankId"
[operationNumber]="selectedOperation"
[methodsGet]="methodsConfig"
[tittleText]="customTitle"
(close)="onModalClose()"
(redirectTo)="onRedirectToModule($event)"
/>
`
})
export class MyComponent {
showModal = false;
selectedBankId = 'bank123';
selectedOperation = 'OP001';
customTitle = 'Movimientos Relacionados Personalizados';
methodsConfig: CbmRelacionshipMovementsModel.TMethodsGet = {
income_banking_transaction: {
repository: this.incomeRepository,
methodName: 'getOne',
objectAlias: {
created_at: 'created_at',
date: 'date',
document_number: 'document_number',
document_nomenclature: 'document_nomenclature',
financials_bank_name: 'financials_bank_name',
financials_bank_account_number: 'financials_bank_account_number',
client_business_name: 'client_business_name',
client_document_number: 'client_document_number',
operation_number: 'operation_number',
movement_number: 'movement_number',
beneficiary: 'beneficiary',
total: 'total'
}
}
// ... más configuraciones para otros tipos
};
onModalClose() {
this.showModal = false;
}
onRedirectToModule(event: any) {
console.log('Redirigir a módulo:', event);
// Implementar lógica de redirección
}
}🎯 Propiedades de Entrada (Inputs)
isOpen: boolean
Controla la visibilidad del modal.
// Abrir modal
this.showModal = true;
// Cerrar modal
this.showModal = false;bankId: string (Requerido)
ID del banco para la validación de operación.
bankId = 'bank123';operationNumber: string (Requerido)
Número de operación bancaria a consultar.
operationNumber = 'OP001';methodsGet: TMethodsGet (Requerido)
Configuración de métodos para obtener datos de diferentes módulos.
methodsGet: CbmRelacionshipMovementsModel.TMethodsGet = {
income_banking_transaction: {
repository: this.incomeRepository,
methodName: 'getOne',
objectAlias: {
created_at: 'created_at',
date: 'date',
// ... más aliases
}
}
};tittleText: string
Texto personalizado para el título del modal.
tittleText = 'Movimientos Relacionados';modalId: string
ID único para el modal (generado automáticamente por defecto).
modalId = 'custom-modal-id';📤 Eventos de Salida (Outputs)
open: void
Se emite cuando el modal se abre.
(close)="onModalOpen()"close: void
Se emite cuando el modal se cierra.
(close)="onModalClose()"redirectTo: IModuleAttributes
Se emite cuando se hace clic en el botón de redirección.
(redirectTo)="onRedirectToModule($event)"Interfaz del evento:
interface IModuleAttributes {
collection_origin_name: string;
collection_origin_id: string;
event_module: string;
}🏗️ Arquitectura del Componente
Patrón de Diseño
El componente sigue el patrón Repository integrado con Signals de Angular:
CbmRelationshipMovementsComponent
├── Signals para estado reactivo
├── Efectos para manejo del DOM
├── Animaciones personalizadas
├── Integración con repositorios CBM
└── Manejo de errores centralizadoEstados Internos
// Estado de carga de operaciones
statusOfFetchOperations: Signal<TStatus> = signal('init');
// Datos del módulo de origen
moduleAtributesResponse: Signal<IModuleAttributes | null>;
// Datos de la operación
operationNumbers: Signal<ValidationOperationResponse.Data | null>;
// Datos principales del movimiento
getData: Signal<MovementData | null>;🎨 Características Visuales
Animaciones
- Entrada/Salida: Transiciones suaves con opacidad y transformación
- Loading: Skeleton loader durante la carga de datos
- Hover: Efectos visuales en elementos interactivos
Diseño Responsive
- Mobile-first: Optimizado para dispositivos móviles
- Tabla responsive: Scroll horizontal en pantallas pequeñas
- Alturas dinámicas: Máximo 60svh para evitar overflow
Tema y Estilos
- Tailwind CSS: Framework de utilidades integrado
- Shadow DOM: Encapsulación completa de estilos
- Colores temáticos: Paleta consistente con el sistema CBM
📊 Tipos de Transacciones Soportadas
El componente reconoce automáticamente diferentes tipos de transacciones:
| Tipo | Descripción | Etiqueta |
|------|-------------|----------|
| income_banking_transaction | Transacción bancaria de ingreso | "Transacción bancaria de ingreso" |
| outgoing_banking_transaction | Transacción bancaria de egreso | "Transacción bancaria de egreso" |
| card_settlement | Liquidación de tarjeta | "Liquidación de tarjeta" |
| deposit_cheque | Depósito de cheque | "Depósito de cheque recibidos" |
| down_payment | Anticipo de clientes | "Anticipo de clientes" |
| income | Cobro a clientes | "Cobro a clientes" |
| cash_liquidation | Liquidación de efectivo | "Liquidación de efectivo" |
🔧 Configuración Avanzada
Configuración de Repositorios
// Configuración completa para un repositorio
income_banking_transaction: {
repository: this.incomeRepository, // Instancia del repositorio
methodName: 'getOne', // Método a ejecutar (opcional)
objectAlias: { // Mapeo de propiedades
created_at: 'created_at',
date: 'date',
document_number: 'document_number',
// ... más mappings
}
}Mapeo de Propiedades Anidadas
// Para propiedades anidadas en objetos
objectAlias: {
financials_bank_name: ['financials', 'bank', 'name'],
client_document_number: ['client', 'document_number']
}Arrays y Conteos
// Para contar elementos únicos en arrays
objectAlias: {
total_clients: ['clients', 'document_number'] // Contará clientes únicos
}🚀 Ejemplos de Uso
Ejemplo Básico
@Component({
selector: 'app-bank-transaction-viewer',
standalone: true,
imports: [CbmRelationshipMovementsComponent],
template: `
<div class="transaction-viewer">
<button (click)="openModal()" class="btn-primary">
Ver Movimientos Relacionados
</button>
<cbm-relationship-movements
[isOpen]="showModal"
[bankId]="bankId"
[operationNumber]="operationNumber"
[methodsGet]="methodsConfig"
(close)="showModal = false"
(redirectTo)="navigateToModule($event)"
/>
</div>
`
})
export class BankTransactionViewerComponent {
showModal = false;
bankId = 'BANK_001';
operationNumber = 'OP_2024_001';
methodsConfig = {
income_banking_transaction: {
repository: this.incomeRepo,
objectAlias: { /* configuración */ }
}
};
openModal() {
this.showModal = true;
}
navigateToModule(event: any) {
// Implementar navegación al módulo correspondiente
console.log('Navegar a:', event.collection_origin_name);
}
}Ejemplo con Formulario Reactivo
@Component({
selector: 'app-transaction-form',
standalone: true,
imports: [ReactiveFormsModule, CbmRelationshipMovementsComponent],
template: `
<form [formGroup]="transactionForm" (ngSubmit)="onSubmit()">
<input formControlName="bankId" placeholder="ID del banco">
<input formControlName="operationNumber" placeholder="Número de operación">
<button type="button" (click)="previewMovements()">
Vista Previa de Movimientos
</button>
<cbm-relationship-movements
[isOpen]="showPreview"
[bankId]="transactionForm.get('bankId')?.value"
[operationNumber]="transactionForm.get('operationNumber')?.value"
[methodsGet]="methodsConfig"
(close)="showPreview = false"
/>
</form>
`
})
export class TransactionFormComponent {
transactionForm = this.fb.group({
bankId: ['', Validators.required],
operationNumber: ['', Validators.required]
});
showPreview = false;
constructor(private fb: FormBuilder) {}
previewMovements() {
if (this.transactionForm.valid) {
this.showPreview = true;
}
}
onSubmit() {
// Procesar formulario
}
}Ejemplo con Signals (Angular 17+)
@Component({
selector: 'app-signals-integration',
standalone: true,
imports: [CbmRelationshipMovementsComponent],
template: `
<div class="signals-demo">
<div class="controls">
<select [(ngModel)]="selectedBank">
<option *ngFor="let bank of banks()" [value]="bank.id">
{{ bank.name }}
</option>
</select>
<input [(ngModel)]="operationInput" placeholder="Número de operación">
<button (click)="loadMovements()" [disabled]="!canLoad()">
Cargar Movimientos
</button>
</div>
<cbm-relationship-movements
[isOpen]="modalOpen()"
[bankId]="selectedBank"
[operationNumber]="operationInput"
[methodsGet]="methodsConfig"
(close)="modalOpen.set(false)"
(redirectTo)="handleRedirect($event)"
/>
</div>
`
})
export class SignalsIntegrationComponent {
// Signals
banks = signal<Bank[]>([]);
selectedBank = signal('');
operationInput = signal('');
modalOpen = signal(false);
// Computed
canLoad = computed(() =>
this.selectedBank().length > 0 && this.operationInput().length > 0
);
loadMovements() {
this.modalOpen.set(true);
}
handleRedirect(event: any) {
// Lógica de redirección con signals
console.log('Redirigiendo a:', event);
}
}⚠️ Manejo de Errores
Estados de Error
// Estados posibles del componente
type TStatus = 'init' | 'loading' | 'success' | 'failed';Manejo de Errores HTTP
// El componente maneja automáticamente errores de:
- Validación de operaciones bancarias
- Consulta de datos relacionados
- Errores de red y conectividadNotificaciones de Error
El componente integra automáticamente con CbmNotificationService para mostrar errores:
// Errores se muestran automáticamente como toasts
// Tipo: 'toastRight', Status: 'error'🎭 Animaciones Personalizadas
Configuración de Animaciones
// Animación de fade in/out
export const fadeInOutAnimation = trigger('fadeInOutAnimation', [
transition(':enter', [
style({ opacity: 0 }),
animate('100ms ease-out', style({ opacity: 1 }))
]),
transition(':leave', [
style({ opacity: 1 }),
animate('100ms ease-in', style({ opacity: 0 }))
])
]);
// Animación del modal
export const modalAnimation = trigger('modalAnimation', [
transition(':enter', [
style({ transform: 'translate(-50%, -100%)', opacity: 0 }),
animate('300ms ease-out', style({ transform: 'translate(-50%, -50%)', opacity: 1 }))
]),
transition(':leave', [
animate('300ms ease-in', style({ transform: 'translate(-50%, -100%)', opacity: 0 }))
])
]);📋 Dependencias
Peer Dependencies (Requeridas)
{
"@angular/common": ">=20.1.5",
"@angular/core": ">=20.1.5",
"@cbm-common/notification-service": "0.0.x",
"@cbm-common/empty": "0.0.x",
"@cbm-common/bank-movements-repository": "0.0.x",
"@cbm-common/tooltip-directive": "0.0.x"
}Dependencias de Desarrollo
{
"tailwindcss": "^4.1.11",
"postcss": "^8.5.6",
"@tailwindcss/postcss": "^4.1.11"
}🛠️ Desarrollo
Estructura del Proyecto
relationship-movements-modal/
├── src/
│ ├── lib/
│ │ ├── relationship-movements.component.ts # Componente principal
│ │ ├── relationship-movements.component.html # Template
│ │ ├── relationship-movements.component.css # Estilos base
│ │ ├── styles.css # Estilos Tailwind
│ │ ├── animations.ts # Animaciones Angular
│ │ ├── type.ts # Tipos TypeScript
│ │ └── index.ts # Exportaciones
│ └── public-api.ts # API pública
├── ng-package.json # Configuración empaquetado
├── package.json # Dependencias
└── README.md # Esta documentaciónConstrucción
# Construir la librería
ng build relationship-movements-modal
# Construir en modo watch
ng build relationship-movements-modal --watch
# Construir para producción
ng build relationship-movements-modal --configuration productionPruebas
# Ejecutar pruebas unitarias
ng test relationship-movements-modal
# Ejecutar pruebas con coverage
ng test relationship-movements-modal --code-coverageDesarrollo con Tailwind
# Compilar estilos Tailwind
npm run tailwind
# Modo watch para desarrollo
npm run tailwind -- --watch🎯 Mejores Prácticas
1. Configuración Centralizada
// config/relationship-movements.config.ts
export const RELATIONSHIP_MOVEMENTS_CONFIG = {
defaultTitle: 'Movimientos Relacionados',
supportedModules: {
income_banking_transaction: { /* config */ },
outgoing_banking_transaction: { /* config */ },
// ... más módulos
}
};2. Manejo de Estado Global
@Injectable({ providedIn: 'root' })
export class RelationshipMovementsFacade {
modalState$ = this.store.select(selectModalState);
openModal(operationData: OperationData) {
this.store.dispatch(openRelationshipModal({ operationData }));
}
closeModal() {
this.store.dispatch(closeRelationshipModal());
}
}3. Lazy Loading
// Para mejorar rendimiento en aplicaciones grandes
const routes: Routes = [
{
path: 'transactions',
loadComponent: () => import('./transaction-viewer.component')
.then(m => m.TransactionViewerComponent)
}
];🤝 Contribución
- Fork el repositorio
- Crea una rama para tu feature (
git checkout -b feature/nueva-funcionalidad) - Commit tus cambios (
git commit -am 'Agrega nueva funcionalidad') - Push a la rama (
git push origin feature/nueva-funcionalidad) - Abre un Pull Request
📄 Licencia
Este proyecto está bajo la Licencia MIT - ver el archivo LICENSE para más detalles.
📞 Soporte
Para soporte técnico o reportes de bugs, contacta al equipo de desarrollo de CBM:
- 📧 Email: [email protected]
- 💬 Slack: #desarrollo-cbm
- 📋 Issues: GitHub Issues
🔄 Changelog
v0.0.1
- ✅ Componente modal standalone con animaciones personalizadas
- ✅ Integración completa con repositorios CBM
- ✅ Soporte para múltiples tipos de transacciones bancarias
- ✅ Sistema de redirección a módulos relacionados
- ✅ Diseño responsive con Tailwind CSS
- ✅ Manejo de estado reactivo con Signals
- ✅ Encapsulación Shadow DOM para estilos
- ✅ Documentación completa en español
Nota: Este componente está diseñado para trabajar con el ecosistema CBM. Asegúrate de tener configuradas todas las dependencias peer antes de usar el componente.
