import { Component, OnInit } from '@angular/core';
import { IonContent } from '@ionic/angular/standalone';
import { ModelRendererComponent } from 'src/lib/components/model-renderer/model-renderer.component';
import { HeaderComponent } from 'src/app/components/header/header.component';
import { ContainerComponent } from 'src/app/components/container/container.component';
import { ListComponent } from 'src/lib/components/list/list.component';
import { NgxModelPageDirective } from 'src/lib/engine/NgxModelPageDirective';
import { EmptyStateComponent } from 'src/lib/components';
import { TranslatePipe } from '@ngx-translate/core';
import { ICrudFormEvent, ITabItem } from 'src/lib/engine/interfaces';
import { ProductLayout } from 'src/app/ew/layouts/ProductLayout';
import { Product } from 'src/app/ew/fabric/Product';
import { CardComponent } from 'src/lib/components/card/card.component';
import { ProductHandler } from 'src/app/ew/fabric/handlers/ProductHandler';
import { AppModalDiffsComponent } from 'src/app/components/modal-diffs/modal-diffs.component';
import { EpiTabs } from 'src/app/ew/utils/constants';
import { OperationKeys } from '@decaf-ts/db-decorators';
import { Model } from '@decaf-ts/decorator-validation';
import { AppProductItemComponent } from 'src/app/components/product-item/product-item.component';
import { AppCardTitleComponent } from 'src/app/components/card-title/card-title.component';
import { KeyValue } from 'src/lib/engine/types';
import { ProductStrength } from 'src/app/ew/fabric';
import { getModelAndRepository } from 'src/lib/engine';
import { Condition } from '@decaf-ts/core';
/**
* @description Angular component page for CRUD operations on dynamic model entities.
* @summary The ModelPage component provides a comprehensive interface for performing Create, Read, Update,
* and Delete operations on any registered model entity within the Decaf framework. This component dynamically
* adapts to different model types and operations, providing a unified interface for data manipulation. It
* integrates with the repository pattern for data access, supports real-time data refresh, and provides user
* feedback through toast notifications and navigation management.
*
* Key features include:
* - Dynamic model resolution based on model name
* - Support for all CRUD operations with operation-specific UI adaptation
* - Automatic repository instantiation and management
* - Integration with Angular routing for navigation flow
* - Error handling with comprehensive logging
* - Real-time data refresh and cache management
* - Toast notifications for user feedback
* - Responsive layout with Ionic components
*
* @param {OperationKeys} operation - The CRUD operation to perform (CREATE, READ, UPDATE, DELETE)
* @param {string} modelName - The name of the model class to operate on
* @param {string} modelId - The unique identifier of the model instance for read/update/delete operations
*
* @class ModelPage
* @example
* ```typescript
* // Usage in routing configuration
* {
* path: 'user/:modelId',
* component: ModelPage,
* data: {
* modelName: 'User',
* operation: OperationKeys.READ
* }
* }
*
* // Direct component usage
* <app-model
* modelName="Product"
* [operation]="OperationKeys.CREATE"
* (submit)="handleSubmit($event)">
* </app-model>
* ```
*
* @mermaid
* sequenceDiagram
* participant U as User
* participant MP as ModelPage
* participant R as Repository
* participant RS as RouterService
* participant T as ToastComponent
* participant L as Logger
*
* U->>MP: Navigate to page
* MP->>MP: ngOnInit()
* MP->>L: Initialize logger
*
* MP->>MP: ionViewWillEnter()
* MP->>MP: Set allowed operations
* MP->>MP: refresh(modelId)
*
* alt Operation is READ/UPDATE/DELETE
* MP->>R: handleGet(modelId)
* R->>R: read(modelId)
* R-->>MP: Return model data
* MP->>MP: Set model
* end
*
* U->>MP: Submit form
* MP->>MP: handleEvent(submitEvent)
* MP->>MP: handleSubmit(event)
* MP->>MP: parseData(event.data)
*
* alt Operation is CREATE
* MP->>R: create(data)
* else Operation is UPDATE
* MP->>R: update(data)
* else Operation is DELETE
* MP->>R: delete(data)
* end
*
* R-->>MP: Return operation result
* MP->>R: refresh(modelName, operation, modelId)
* MP->>RS: backToLastPage()
* MP->>T: inform(success message)
*
* alt Error occurs
* MP->>L: error(error)
* MP->>MP: throw Error
* end
*/
@Component({
standalone: true,
selector: 'app-products',
templateUrl: './products.page.html',
providers: [AppModalDiffsComponent, AppProductItemComponent],
imports: [
IonContent,
AppCardTitleComponent,
ModelRendererComponent,
TranslatePipe,
ListComponent,
HeaderComponent,
ContainerComponent,
EmptyStateComponent,
],
styleUrls: ['./products.page.scss'],
})
export class ProductsPage extends NgxModelPageDirective implements OnInit {
tabs: ITabItem[] = EpiTabs;
constructor() {
super('product');
}
async ngOnInit(): Promise<void> {
this.model = !this.operation ? new Product() : new ProductLayout();
this.enableCrudOperations([OperationKeys.DELETE]);
// keep init after model selection
this.locale = 'product';
this.title = `${this.locale}.title`;
this.route = 'products';
await this.initialize();
// if (this.operation === OperationKeys.CREATE) {
// const model = (await this.handleRead('00000000000013')) as ProductLayout;
// if ((this.model as KeyValue)['product']) {
// (this.model as KeyValue)['product'].productCode = `${Date.now()}`;
// }
// // Object.assign((this.model as any).epi, {
// // strengths: [{ strengths: '500mg', substance: 'tablet' }],
// // });
// }
// if (this.modelId) {
// const strengths = getModelAndRepository('ProductStrength');
// if (strengths) {
// const { repository } = strengths;
// const query = await repository
// .select()
// .where(Condition.attr('productCode' as keyof Model).eq(this.modelId))
// .execute();
// console.log(query);
// }
// }
// console.log(this.model);
// const images = getModelAndRepository('ProductImage');
// if (images) {
// const { repository } = images;
// const query = await repository
// .select()
// .where(Condition.attr('productCode' as keyof Model).eq('00000000000013'))
// .execute();
// console.log('images', query);
// }
// console.log(this.model);
}
}
Source