fam-archetype-app 0.0.1

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 (147) hide show
  1. package/README.md +38 -0
  2. package/package.json +25 -0
  3. package/src/collection.json +10 -0
  4. package/src/fam-archetype-app/files/.editorconfig +16 -0
  5. package/src/fam-archetype-app/files/.prettierignore +15 -0
  6. package/src/fam-archetype-app/files/.prettierrc.json +29 -0
  7. package/src/fam-archetype-app/files/LICENSE.md +21 -0
  8. package/src/fam-archetype-app/files/README.md +59 -0
  9. package/src/fam-archetype-app/files/angular.json.template +178 -0
  10. package/src/fam-archetype-app/files/cli +361 -0
  11. package/src/fam-archetype-app/files/eslint.config.js +89 -0
  12. package/src/fam-archetype-app/files/package-lock.json.template +18812 -0
  13. package/src/fam-archetype-app/files/package.json.template +62 -0
  14. package/src/fam-archetype-app/files/src/assets/fonts/DiBaScreen-Regular.woff2 +0 -0
  15. package/src/fam-archetype-app/files/src/assets/translations/translations-ca.json +284 -0
  16. package/src/fam-archetype-app/files/src/assets/translations/translations-en.json +28 -0
  17. package/src/fam-archetype-app/files/src/assets/translations/translations-es.json +28 -0
  18. package/src/fam-archetype-app/files/src/core/layout/component/footer/footer.component.html.template +3 -0
  19. package/src/fam-archetype-app/files/src/core/layout/component/footer/footer.component.scss +8 -0
  20. package/src/fam-archetype-app/files/src/core/layout/component/layout/layout.component.html +19 -0
  21. package/src/fam-archetype-app/files/src/core/layout/component/layout/layout.component.scss +28 -0
  22. package/src/fam-archetype-app/files/src/core/layout/component/main-info-popup/main-info-popup.component.html +33 -0
  23. package/src/fam-archetype-app/files/src/core/layout/component/main-info-popup/main-info-popup.component.scss +3 -0
  24. package/src/fam-archetype-app/files/src/core/layout/component/menu/menu.component.html +3 -0
  25. package/src/fam-archetype-app/files/src/core/layout/component/menu/menu.component.scss +163 -0
  26. package/src/fam-archetype-app/files/src/core/layout/component/menuitem/menuitem.component.html +39 -0
  27. package/src/fam-archetype-app/files/src/core/layout/component/menuitem/menuitem.component.scss +44 -0
  28. package/src/fam-archetype-app/files/src/core/layout/component/not-found/not-found.component.html +12 -0
  29. package/src/fam-archetype-app/files/src/core/layout/component/not-found/not-found.component.scss +17 -0
  30. package/src/fam-archetype-app/files/src/core/layout/component/sidebar/sidebar.component.html +13 -0
  31. package/src/fam-archetype-app/files/src/core/layout/component/sidebar/sidebar.component.scss +33 -0
  32. package/src/fam-archetype-app/files/src/core/layout/component/top-menu/top-menu.component.html +12 -0
  33. package/src/fam-archetype-app/files/src/core/layout/component/top-menu/top-menu.component.scss +9 -0
  34. package/src/fam-archetype-app/files/src/core/layout/component/topbar/_mixins.scss +8 -0
  35. package/src/fam-archetype-app/files/src/core/layout/component/topbar/topbar.component.html.template +45 -0
  36. package/src/fam-archetype-app/files/src/core/layout/component/topbar/topbar.component.scss +77 -0
  37. package/src/fam-archetype-app/files/src/environments/environment.dev.ts.template +12 -0
  38. package/src/fam-archetype-app/files/src/environments/environment.int.ts.template +12 -0
  39. package/src/fam-archetype-app/files/src/environments/environment.pre.ts.template +12 -0
  40. package/src/fam-archetype-app/files/src/environments/environment.ts.template +12 -0
  41. package/src/fam-archetype-app/files/src/index.html.template +18 -0
  42. package/src/fam-archetype-app/files/src/shared/filters/diba-filters/diba-filters.component.html +69 -0
  43. package/src/fam-archetype-app/files/src/shared/filters/diba-filters/diba-filters.component.scss +0 -0
  44. package/src/fam-archetype-app/files/src/shared/styles/_movements.scss +19 -0
  45. package/src/fam-archetype-app/files/src/shared/styles/global/_core.scss +20 -0
  46. package/src/fam-archetype-app/files/src/shared/styles/global/_icons.scss +37 -0
  47. package/src/fam-archetype-app/files/src/shared/styles/global/_tooltips.scss +14 -0
  48. package/src/fam-archetype-app/files/src/shared/styles/global/_typography.scss +68 -0
  49. package/src/fam-archetype-app/files/src/shared/styles/global/_utils.scss +24 -0
  50. package/src/fam-archetype-app/files/src/shared/styles/global/layout.scss +5 -0
  51. package/src/fam-archetype-app/files/src/shared/table/column-visibility-selector/column-visibility-selector.component.html +10 -0
  52. package/src/fam-archetype-app/files/src/shared/table/column-visibility-selector/column-visibility-selector.component.scss +0 -0
  53. package/src/fam-archetype-app/files/src/shared/table/diba-table/diba-table.component.html +136 -0
  54. package/src/fam-archetype-app/files/src/shared/table/diba-table/diba-table.component.scss +0 -0
  55. package/src/fam-archetype-app/files/src/styles.scss +109 -0
  56. package/src/fam-archetype-app/files/src/tailwind.css +3 -0
  57. package/src/fam-archetype-app/files/tailwind.config.js +36 -0
  58. package/src/fam-archetype-app/files/tools/cli/TelosysTools/commands/commands.txt +1 -0
  59. package/src/fam-archetype-app/files/tools/cli/TelosysTools/commands/db_to_entities.txt +1 -0
  60. package/src/fam-archetype-app/files/tools/cli/TelosysTools/commands/test_db_connection.txt +1 -0
  61. package/src/fam-archetype-app/files/tools/cli/TelosysTools/databases.yaml +188 -0
  62. package/src/fam-archetype-app/files/tools/cli/TelosysTools/downloads/.keep +0 -0
  63. package/src/fam-archetype-app/files/tools/cli/TelosysTools/lib/.keep +0 -0
  64. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamActivitat.entity +26 -0
  65. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamActivitatsUbicacio.entity +40 -0
  66. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamAlumne.entity +76 -0
  67. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamArea.entity +33 -0
  68. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamComanda.entity +37 -0
  69. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamCurs.entity +50 -0
  70. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamDocument.entity +53 -0
  71. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamDocumentTipus.entity +26 -0
  72. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamEntitatBase.entity +84 -0
  73. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamExpedient.entity +71 -0
  74. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamExpedientDocument.entity +51 -0
  75. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamExpedientEstat.entity +26 -0
  76. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamExpedientTipus.entity +26 -0
  77. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamJerarquia.entity +33 -0
  78. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamLinia.entity +56 -0
  79. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamMatricula.entity +63 -0
  80. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamTipusArticle.entity +26 -0
  81. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamUbicacio.entity +35 -0
  82. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FamZona.entity +27 -0
  83. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/Funcionalitat.entity +65 -0
  84. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/FuncionalitatGrupFunc.entity +58 -0
  85. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/GrupFuncionalitat.entity +54 -0
  86. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/PerfilGrupFuncionalitat.entity +50 -0
  87. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/VusPerfil.entity +31 -0
  88. package/src/fam-archetype-app/files/tools/cli/TelosysTools/models/app/model.yaml +4 -0
  89. package/src/fam-archetype-app/files/tools/cli/TelosysTools/telosys-tools.cfg +31 -0
  90. package/src/fam-archetype-app/files/tools/cli/TelosysTools/telosys.env +5 -0
  91. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/README.md +12 -0
  92. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/database.properties +23 -0
  93. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/include/init_var_entity.vm +169 -0
  94. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/include/macros.vm +218 -0
  95. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/app_config_ts.vm +56 -0
  96. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/app_routes_ts.vm +21 -0
  97. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/core/layout/component/menu/menu_component_ts.vm +30 -0
  98. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/core/layout/component/top-menu/top-menu_component_ts.vm +36 -0
  99. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/core/layout/service/menu_model_service_ts.vm +49 -0
  100. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/create-Xxx_use-case_ts.vm +18 -0
  101. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/create-file-Xxx_use-case_ts.vm +17 -0
  102. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/delete-Xxx_use-case_ts.vm +17 -0
  103. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/download-Xxx-file_use-case_ts.vm +24 -0
  104. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/find-Xxx_use-case_ts.vm +18 -0
  105. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/search-Xxx_use-case_ts.vm +25 -0
  106. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/application/update-Xxx_use-case_ts.vm +18 -0
  107. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/domain/Xxx_entity_ts.vm +36 -0
  108. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/domain/Xxx_repository_interface_ts.vm +27 -0
  109. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/mappers/Xxx_jsona_mapper_ts.vm +52 -0
  110. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/mappers/Xxx_mapper_ts.vm +36 -0
  111. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/Xxx_routes_ts.vm +15 -0
  112. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/detail/Xxx_detail_html.vm +178 -0
  113. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/detail/Xxx_detail_scss.vm +0 -0
  114. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/detail/Xxx_detail_spec_ts.vm +29 -0
  115. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/detail/Xxx_detail_ts.vm +382 -0
  116. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/list/Xxx_list_html.vm +37 -0
  117. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/list/Xxx_list_scss.vm +10 -0
  118. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/list/Xxx_list_spec_ts.vm +29 -0
  119. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/pages/list/Xxx_list_ts.vm +430 -0
  120. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/inbound/resources/Xxx_resource_ts.vm +43 -0
  121. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/modules/infrastructure/outbound/Xxx_repository_impl_ts.vm +162 -0
  122. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/main-angular/test_code.vm +3 -0
  123. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/templates.cfg +52 -0
  124. package/src/fam-archetype-app/files/tools/cli/TelosysTools/templates/fam-app-templates/tools-test/test-api_Xxx_rest.vm +181 -0
  125. package/src/fam-archetype-app/files/tools/cli/telosys +5 -0
  126. package/src/fam-archetype-app/files/tools/cli/telosys-cli-4.2.0-001.jar +0 -0
  127. package/src/fam-archetype-app/files/tools/cli/telosys-cli.cfg +55 -0
  128. package/src/fam-archetype-app/files/tools/cli/telosys-term.sh +30 -0
  129. package/src/fam-archetype-app/files/tools/cli/telosys.bat +4 -0
  130. package/src/fam-archetype-app/files/tools/cli/telosys.ico +0 -0
  131. package/src/fam-archetype-app/files/tools/db/develop/data/.keep +0 -0
  132. package/src/fam-archetype-app/files/tools/db/production/data/.keep +0 -0
  133. package/src/fam-archetype-app/files/tools/db/production/migrations/.keep +0 -0
  134. package/src/fam-archetype-app/files/tools/docs/.keep +0 -0
  135. package/src/fam-archetype-app/files/tools/test/test-api.rest +80 -0
  136. package/src/fam-archetype-app/files/tsconfig.app.json +15 -0
  137. package/src/fam-archetype-app/files/tsconfig.json +42 -0
  138. package/src/fam-archetype-app/files/tsconfig.spec.json +15 -0
  139. package/src/fam-archetype-app/files/vercel.json +9 -0
  140. package/src/fam-archetype-app/index.d.ts +2 -0
  141. package/src/fam-archetype-app/index.js +18 -0
  142. package/src/fam-archetype-app/index.js.map +1 -0
  143. package/src/fam-archetype-app/index_spec.d.ts +1 -0
  144. package/src/fam-archetype-app/index_spec.js +23 -0
  145. package/src/fam-archetype-app/index_spec.js.map +1 -0
  146. package/src/fam-archetype-app/schema.json +21 -0
  147. package/tsconfig.json +24 -0
@@ -0,0 +1,430 @@
1
+ #parse("include/macros.vm")
2
+ ## --------------------------------------------------
3
+ #checkId($entity)
4
+ #parse("include/init_var_entity.vm")
5
+ #parse("include/macros.vm")
6
+ ##---------------------------------------------------
7
+ import { Component, Input, SimpleChanges, Type } from '@angular/core';
8
+ import { CommonModule } from '@angular/common';
9
+ import { RouterModule } from '@angular/router';
10
+ import { ${entityName} } from '../../../../domain/#kebabCase("${entityName}").entity';
11
+ import { Search${entityName}UseCase } from '../../../../application/search-#kebabCase("${entityName}").use-case';
12
+ import { Delete${entityName}UseCase } from '../../../../application/delete-#kebabCase("${entityName}").use-case';
13
+ import { PrimeNgTranslationPipe } from '@core/pipes/primeng-translation.pipe';
14
+ import { Button } from 'primeng/button';
15
+ import { DibaTableComponent } from '@shared/table/diba-table/diba-table.component';
16
+ import { JsonApiMeta } from '@shared/models/json-api-meta.entity';
17
+ import { UtilsService } from '@shared/service/utils.service';
18
+ import { Column } from '@shared/table/domain/column.entity';
19
+ import { ColumnType } from '@shared/table/domain/column-type.enum';
20
+ import { DropdownModule } from 'primeng/dropdown';
21
+ import { CalendarModule } from 'primeng/calendar';
22
+ import { InputTextModule } from 'primeng/inputtext';
23
+ import { FormsModule } from '@angular/forms';
24
+ import { Filter } from '@shared/filters/domain/filter.entity';
25
+ import { FilterType } from '@shared/filters/domain/filter-type.enum';
26
+ import { DibaFiltersComponent } from '@shared/filters/diba-filters/diba-filters.component';
27
+ import { FilterOperator } from '@shared/filters/domain/filter-operator.enum';
28
+ import { ${entityName}DetailComponent } from '../#kebabCase("${entityName}")-detail/#kebabCase("${entityName}")-detail.component';
29
+
30
+ #foreach( $link in $toOneLinks )
31
+ #if( ${entityName} != ${link.fieldType})
32
+ #if( $velocityCount == 1 )
33
+ //to One
34
+ #end
35
+ import { ${link.fieldType} } from '../../../../../#kebabCase("${link.fieldType}")/domain/#kebabCase("${link.fieldType}").entity';
36
+ import { Search${link.fieldType}UseCase } from '@modules/#kebabCase("${link.fieldType}")/application/search-#kebabCase("${link.fieldType}").use-case';
37
+ #end
38
+ #end
39
+
40
+ @Component({
41
+ selector: 'app-#kebabCase("${entityName}")-list',
42
+ imports: [
43
+ CommonModule,
44
+ RouterModule,
45
+ PrimeNgTranslationPipe,
46
+ Button,
47
+ DibaTableComponent,
48
+ DibaFiltersComponent,
49
+ DropdownModule,
50
+ CalendarModule,
51
+ InputTextModule,
52
+ FormsModule],
53
+ templateUrl: './#kebabCase("${entityName}")-list.component.html',
54
+ styleUrl: './#kebabCase("${entityName}")-list.component.scss'
55
+ })
56
+ export class ${entityName}ListComponent {
57
+
58
+ // NUEVO: modo embebido y parámetros opcionales
59
+ @Input() embedded = false; // si true: estamos dentro del detalle de zona
60
+ @Input() parentId?: string | number; // id de la zona a fijar
61
+ @Input() showFilters = true; // esconder barra de filtros si se quiere
62
+ @Input() pageSizeEmbedded = 5; // tamaño de página por defecto en embebido
63
+ @Input() parent = ""; // Entidad padre que llama al listado envedido
64
+ detailComponent: Type<any> = ${entityName}DetailComponent;
65
+
66
+ // Active filters
67
+ FilterType = FilterType;
68
+ filters: Filter[] = [
69
+ #set( $existMandatoryAtribiute = false)
70
+ #foreach( $attribute in $mandatoryInList )
71
+ #set( $existMandatoryAtribiute = true)
72
+ #if( $attribute.type == "String" || $attribute.type == "string" )
73
+ {
74
+ label: "#snakeLowerCase("${attribute.name}")",
75
+ name:"#snakeLowerCase("${attribute.name}")",
76
+ type: FilterType.TEXT,
77
+ operator: FilterOperator.LIKE,
78
+ value: ""
79
+ }
80
+ #elseif( $attribute.type == "long" || $attribute.type == "Long" || $attribute.type == "int" || $attribute.type == "integer" || $attribute.type == "Integer")
81
+ {
82
+ label: "#snakeLowerCase("${attribute.name}")_MIN",
83
+ name:"#snakeLowerCase("${attribute.name}")",
84
+ type: FilterType.NUMBER,
85
+ operator: FilterOperator.GTE,
86
+ value: ""
87
+ },
88
+ {
89
+ label: "#snakeLowerCase("${attribute.name}")_MAX",
90
+ name:"#snakeLowerCase("${attribute.name}")",
91
+ type: FilterType.NUMBER,
92
+ operator: FilterOperator.LTE,
93
+ value: ""
94
+ }
95
+ #elseif( $attribute.type == "LocalDate" || $attribute.type == "localdate" || $attribute.type == "Date" || $attribute.type == "date")
96
+ {
97
+ label: "#snakeLowerCase("${attribute.name}")_FROM",
98
+ name:"#snakeLowerCase("${attribute.name}")",
99
+ type: FilterType.DATE,
100
+ operator: FilterOperator.GTE,
101
+ value: ""
102
+ },
103
+ {
104
+ label: "#snakeLowerCase("${attribute.name}")_TO",
105
+ name:"#snakeLowerCase("${attribute.name}")",
106
+ type: FilterType.DATE,
107
+ operator: FilterOperator.LTE,
108
+ value: ""
109
+ }
110
+ #elseif( $attribute.type == "Boolean" || $attribute.type == "boolean")
111
+ {
112
+ label: "#snakeLowerCase("${attribute.name}")",
113
+ name:"#snakeLowerCase("${attribute.name}")",
114
+ type: FilterType.BOOLEAN,
115
+ operator: FilterOperator.EQ,
116
+ value: "",
117
+ selectValues: [
118
+ { label: '\u2009', value: null }, // Empty option
119
+ { label: 'Sí', value: true },
120
+ { label: 'No', value: false }]
121
+ }
122
+ #else
123
+ {
124
+ label: "#snakeLowerCase("${attribute.name}")",
125
+ name:"#snakeLowerCase("${attribute.name}")",
126
+ type: FilterType.TEXT,
127
+ operator: FilterOperator.LIKE,
128
+ value: ""
129
+ }
130
+ #end
131
+ #comma( $foreach.hasNext )
132
+ #end
133
+ #foreach( $link in $mandatoryToOneLinksInList )
134
+ #set($fieldShowFront = $link.tagValue("fieldShowFront", "id"))
135
+ #if( $existMandatoryAtribiute == true && $velocityCount == 1)
136
+ ,
137
+ #end
138
+ {
139
+ label: "#snakeLowerCase("${link.fieldName}").#snakeLowerCase("${fieldShowFront}")",
140
+ name:"#snakeLowerCase("${link.fieldName}").id",
141
+ type: FilterType.SELECT,
142
+ operator: FilterOperator.EQ,
143
+ value: "",
144
+ selectValues: []
145
+ } #comma( $foreach.hasNext )
146
+ #end
147
+ ];
148
+
149
+ //List Data
150
+ #camelCase("${entityName}")List: ${entityName}[] = [];
151
+ meta: JsonApiMeta = {
152
+ page: {
153
+ size: 5, //Rows
154
+ totalElements: 5, //Total Rows
155
+ totalPages: 1, //Total Pages
156
+ number: 1 //Current Page
157
+ }
158
+ };
159
+
160
+ //List params
161
+ rowsPerPageOptions: number[] = [5, 10, 20, 50, 100];
162
+
163
+ //List Columns
164
+ columnasMostrar: Column[] = [
165
+ #set( $existMandatoryAtribiute = false)
166
+ #foreach( $attribute in $mandatoryInList )
167
+ #set( $existMandatoryAtribiute = true)
168
+ {
169
+ field: '#snakeLowerCase("${attribute.name}")',
170
+ header: '#snakeLowerCase("${attribute.name}")',
171
+ type: #columnType("${attribute.type}"),
172
+ #set($pipe = $attribute.tagValue("pipe", "undefined"))
173
+ #set($pipeFormatted = "#if($pipe)'$pipe'#else undefined#end")
174
+ pipe: $pipeFormatted
175
+ }#comma( $foreach.hasNext )
176
+ #end
177
+ #foreach( $link in $mandatoryToOneLinksInList )
178
+ #set($fieldShowFront = $link.tagValue("fieldShowFront", "id"))
179
+ #if( $existMandatoryAtribiute == true && $velocityCount == 1)
180
+ ,
181
+ #end
182
+ {
183
+ field: '#snakeLowerCase("${link.fieldName}").#snakeLowerCase("${fieldShowFront}")',
184
+ header: '#snakeLowerCase("${link.fieldName}").#snakeLowerCase("${fieldShowFront}")',
185
+ type: ColumnType.TEXT,
186
+ #set($pipe = $link.tagValue("pipe", "undefined"))
187
+ #set($pipeFormatted = "#if($pipe)'$pipe'#else undefined#end")
188
+ pipe: $pipeFormatted
189
+ } #printTagAsColumnObjects($link "extraField") #comma( $foreach.hasNext )
190
+ #end];
191
+ columnasOcultar: Column[] = [
192
+ #set( $existOptionalAtribiute = false)
193
+ #foreach( $attribute in $optionalInList )
194
+ #set( $existOptionalAtribiute = true)
195
+ {
196
+ field: '#snakeLowerCase("${attribute.name}")',
197
+ header: '#snakeLowerCase("${attribute.name}")',
198
+ type: #columnType("${attribute.type}"),
199
+ #set($pipe = $attribute.tagValue("pipe", "undefined"))
200
+ #set($pipeFormatted = "#if($pipe)'$pipe'#else undefined#end")
201
+ pipe: $pipeFormatted
202
+ } #comma( $foreach.hasNext )
203
+ #end
204
+ #foreach( $link in $optionalToOneLinksInList )
205
+ #set($fieldShowFront = $link.tagValue("fieldShowFront", "id"))
206
+ #if( $existOptionalAtribiute == true && $velocityCount == 1)
207
+ ,
208
+ #end
209
+ {
210
+ field: '#snakeLowerCase("${link.fieldName}").#snakeLowerCase("${fieldShowFront}")',
211
+ header: '#snakeLowerCase("${link.fieldName}").#snakeLowerCase("${fieldShowFront}")',
212
+ type: ColumnType.TEXT,
213
+ #set($pipe = $link.tagValue("pipe", "undefined"))
214
+ #set($pipeFormatted = "#if($pipe)'$pipe'#else undefined#end")
215
+ pipe: $pipeFormatted
216
+ } #printTagAsColumnObjects($link "extraField") #comma( $foreach.hasNext )
217
+
218
+ #end];
219
+ //Search Params
220
+ include: string[] = [
221
+ #foreach( $link in $toOneLinks )
222
+ '#snakeLowerCase("${link.fieldName}")' #printTagValueAsList($link "extraInclude") #comma( $foreach.hasNext )
223
+ #end
224
+ ];
225
+ pagination: {page: number, limit: number} = { page: 1, limit: 10 };
226
+ sort: string = '';
227
+ // CRUD Operations
228
+ selectRows: boolean = true;
229
+ allowEdit: boolean = true;
230
+ allowDelete: boolean = true;
231
+ allowCreate: boolean = true;
232
+ loading: boolean = false;
233
+ #set( $existLinkInListAttribute = false )
234
+ #foreach( $attribute in $mandatoryInList )
235
+ #if( $attribute.hasTag("linkInList") && $attribute.tagValue("linkInList") == "true" )
236
+ #set( $existLinkInListAttribute = true )
237
+ #set( $linkAttribute = $attribute.name )
238
+ #break
239
+ #end
240
+ #if($velocityCount == 1 && $existLinkInListAttribute == false)
241
+ #set( $linkAttribute = $attribute.name )
242
+ #end
243
+ #end
244
+ #set( $existLinkInListToOne = false )
245
+ #foreach( $link in $mandatoryToOneLinksInList )
246
+ #set($isLinkInList = $link.tagValueAsBoolean("linkInList", false))
247
+ #if( $isLinkInList )
248
+ #set( $existLinkInListAttribute = true )
249
+ #set( $existLinkInListToOne = true )
250
+ #set( $fieldShowFrontLinkItem = $link.tagValue("fieldShowFront", "id"))
251
+ #set( $linkAttribute = $link.fieldName )
252
+ #break
253
+ #end
254
+ #end
255
+ #set( $existLinkInListAttribute = true )
256
+
257
+ #if( $existLinkInListAttribute )
258
+ #if( !$existLinkInListToOne)
259
+ linkColumn: string = "#snakeLowerCase($linkAttribute)";
260
+ #else
261
+ linkColumn: string = '#snakeLowerCase("${linkAttribute}").#snakeLowerCase("${fieldShowFrontLinkItem}")';
262
+ #end
263
+ #end
264
+
265
+ constructor(
266
+ private search${entityName}: Search${entityName}UseCase,
267
+ private delete${entityName}: Delete${entityName}UseCase,
268
+ private utils: UtilsService
269
+ #foreach( $link in $mandatoryToOneLinksInList )
270
+ #if( ${entityName} != ${link.fieldType})
271
+ , private search#camelCaseCapitalize("${link.fieldName}"): Search#camelCaseCapitalize("${link.fieldName}")UseCase
272
+ #end#end
273
+ ) {
274
+ this.pagination = { page: this.meta.page.number, limit: this.meta.page.size };
275
+ }
276
+
277
+ async ngOnInit() {
278
+ console.log('${entityName}ListComponent initialized');
279
+ #foreach( $link in $mandatoryToOneLinksInList )
280
+ #set($fieldShowFront = $link.tagValue("fieldShowFront", "id"))
281
+ this.loadDropdownFilter('#snakeLowerCase("${link.fieldName}").#snakeLowerCase("${fieldShowFront}")', '#snakeLowerCase("${fieldShowFront}")', this.search#camelCaseCapitalize("${link.fieldName}"));
282
+ #end
283
+ // si embebido, ajusta paginación y filtros iniciales
284
+ if (this.embedded) {
285
+ this.meta.page.size = this.pageSizeEmbedded;
286
+ #foreach( $link in $mandatoryToOneLinksInList )
287
+ #set($isParentEntity = $link.tagValueAsBoolean("isParentEntity", false))
288
+ #if( $isParentEntity )
289
+ // opcional: si tienes array 'filters' predefinido, quita el filtro por la entidad padre del usuario
290
+ this.filters = (this.filters ?? []).filter(f => f.name !== '#snakeLowerCase("${link.fieldName}").id');
291
+ #end#end
292
+
293
+ // primer search con filtro fijo de zona
294
+ this.newSearch(this.filters ?? []);
295
+ } else {
296
+ // comportamiento actual
297
+ this.newSearch(this.filters ?? []);
298
+ }
299
+ this.search();
300
+ }
301
+
302
+ ngOnChanges(changes: SimpleChanges): void {
303
+ #foreach( $link in $mandatoryToOneLinksInList )
304
+ #set($isParentEntity = $link.tagValueAsBoolean("isParentEntity", false))
305
+ #if( $isParentEntity )
306
+ // si cambia la parentId en modo embebido, relanza la búsqueda
307
+ if (this.embedded && changes['parentId'] && !changes['parentId'].firstChange) {
308
+ this.meta.page.number = 1;
309
+ this.newSearch(this.filters ?? []);
310
+ }
311
+ #end#end
312
+ }
313
+
314
+
315
+ // Filtro fijo por id entidad padre cuando estamos embebidos
316
+ private get fixedParentFilter(): Filter[] {
317
+ if (!this.embedded || !this.parentId) return [];
318
+ #set($firstParent = true)
319
+ #foreach( $link in $mandatoryToOneLinksInList )
320
+ #set($isParentEntity = $link.tagValueAsBoolean("isParentEntity", false))
321
+ #if( $isParentEntity )
322
+ #if( $firstParent )
323
+ #set($firstParent = false)
324
+ if(this.parent === "#camelCaseCapitalize("${link.fieldType}")") {
325
+ return [{
326
+ label: 'parent_filter', // el label es decorativo
327
+ name: '#snakeLowerCase("${link.fieldName}").id',
328
+ operator: FilterOperator.EQ,
329
+ value: String(this.parentId),
330
+ type: FilterType.TEXT
331
+ }];
332
+ }
333
+ #else
334
+ else if(this.parent === "#camelCaseCapitalize("${link.fieldType}")") {
335
+ return [{
336
+ label: 'parent_filter', // el label es decorativo
337
+ name: '#snakeLowerCase("${link.fieldName}").id',
338
+ operator: FilterOperator.EQ,
339
+ value: String(this.parentId),
340
+ type: FilterType.TEXT
341
+ }];
342
+ }
343
+ #end
344
+ #end#end
345
+ #if( !$firstParent )
346
+ else {
347
+ return [];
348
+ }
349
+ #else
350
+ return [];
351
+ #end
352
+
353
+ }
354
+
355
+ async newSearch(event: any) {
356
+ console.log("Event : " + JSON.stringify(event.filters));
357
+ if(event.filters !== undefined) {
358
+ const effectiveFilters = [...(event.filters ?? []), ...this.fixedParentFilter];
359
+ this.filters = effectiveFilters;
360
+ } else if(this.fixedParentFilter.length > 0) {
361
+ const effectiveFilters = [...this.fixedParentFilter];
362
+ this.filters = effectiveFilters;
363
+ }
364
+ this.meta.page.number = 1; // Reset to first page
365
+ this.search();
366
+ }
367
+
368
+ async search() {
369
+ this.loading = true;
370
+ this.pagination = { page: this.meta.page.number, limit: this.meta.page.size };
371
+ let apiResponse = await this.search${entityName}.execute(this.filters, this.include, this.pagination, this.sort);
372
+ this.#camelCase("${entityName}")List = apiResponse.data;
373
+ this.meta = apiResponse.meta;
374
+ this.loading = false;
375
+ console.log("Show #camelCase("${entityName}") - list :", this.#camelCase("${entityName}")List);
376
+ }
377
+
378
+ async cleanFilters(event: any) {
379
+ console.log("Event : " + JSON.stringify(event.filters));
380
+ this.filters = event.filters;
381
+ }
382
+
383
+ delete(id: string): void {
384
+ this.delete${entityName}.execute(id)
385
+ .then(async () => {
386
+ this.search();
387
+ })
388
+ .catch(error => {
389
+ console.error('Error deleting ${entityName}:', error);
390
+ });
391
+ }
392
+
393
+ onPageChange(event: any) {
394
+ //Update pagination based on the event
395
+ this.meta.page.number = event.page;
396
+ this.meta.page.size = event.rows;
397
+ // Call the search method to fetch data for the new page
398
+ this.search();
399
+ }
400
+
401
+ onSortChange(event: any) {
402
+ //Update sort based on the event
403
+ this.sort = this.utils.multiSortMetaToJsonApiSort(event.multisortmeta);
404
+ // Call the search method to fetch data for the new sort
405
+ this.search();
406
+ }
407
+
408
+ onDeleteEvent(event: any) {
409
+ for (const id of event) {
410
+ console.log("Eliminar registro con id: " + id);
411
+ this.delete(id);
412
+ }
413
+ }
414
+
415
+ onPageUpdate(event: any) {
416
+ console.log("Actualizar listado tras edición o creación : " + event);
417
+ this.search();
418
+ }
419
+
420
+ async loadDropdownFilter(label: string, field: string, searchService: any) {
421
+ // Load info for dropdown filter
422
+ const optionsZona = this.utils.mapJsonApiToDropdownOptions((await searchService.execute()).data, field);
423
+ // Añadir la opción vacía al principio
424
+ const optionsWith = [{ label: '\u2009', value: null }, ...optionsZona];
425
+ const filtro = this.filters.find(f => f.label === label);
426
+ if (filtro) {
427
+ filtro.selectValues = optionsWith;
428
+ }
429
+ }
430
+ }
@@ -0,0 +1,43 @@
1
+ #parse("include/macros.vm")
2
+ ## --------------------------------------------------
3
+ #checkId($entity)
4
+ #parse("include/init_var_entity.vm")
5
+ #parse("include/macros.vm")
6
+ ##---------------------------------------------------
7
+
8
+ import { ${entityName} } from '../../../domain/#kebabCase("${entityName}").entity';
9
+ #foreach( $link in $toOneLinks )
10
+ #if(${entityName}!= $link.fieldType)
11
+ import { ${link.fieldType} } from '../../../../#kebabCase("$link.fieldType")/domain/#kebabCase("$link.fieldType").entity';
12
+ #end
13
+ #end
14
+ #foreach( $link in $toManyLinks )
15
+ #set( $genericType = "#extractGenericType($link.fieldType)" )
16
+ #if(${entityName}!= $genericType)
17
+ import { $genericType } from '../../../../#kebabCase("$genericType")/domain/#kebabCase("$genericType").entity';
18
+ #end
19
+ #end
20
+
21
+ export class ${entityName}Resource implements ${entityName} {
22
+ id?: string;
23
+ #foreach( $attribute in $entity.nonKeyAttributes )
24
+ #set( $attributeType = $attribute.wrapperType )
25
+ #snakeLowerCase("$attribute.name")#if($attribute.isNotNull())?#end: #javaTypeToTsType("$attributeType") #if(!$attribute.isNotNull())#tsDefaultValue("$attributeType")#end;
26
+ #end
27
+ #foreach( $link in $toOneLinks )
28
+ #if( $velocityCount == 1 )
29
+ // toOne
30
+ #end
31
+ #snakeLowerCase("${link.fieldName}"): $link.fieldType = {} as $link.fieldType;
32
+ #end
33
+ #foreach( $link in $toManyLinks )
34
+ #if( $velocityCount == 1 )
35
+ // toMany
36
+ #end
37
+ #snakeLowerCase("${link.fieldName}"): #extractGenericType("$link.fieldType")[] = [];
38
+ #end
39
+
40
+ constructor(init?: Partial<${entityName}Resource>) {
41
+ Object.assign(this, init);
42
+ }
43
+ }
@@ -0,0 +1,162 @@
1
+ ## --------------------------------------------------
2
+ #checkId($entity)
3
+ #parse("include/init_var_entity.vm")
4
+ #parse("include/macros.vm")
5
+ ##---------------------------------------------------
6
+ import { ${entityName}RepositoryInterface } from '../../domain/#kebabCase("${entityName}").repository.interface';
7
+ import { ${entityName} } from '../../domain/#kebabCase("${entityName}").entity';
8
+ import { Injectable } from '@angular/core';
9
+ import { HttpClient } from '@angular/common/http';
10
+ import { firstValueFrom, Observable } from 'rxjs';
11
+ import { environment } from '@root/environments/environment';
12
+ import { Jsona } from 'jsona';
13
+ import { ${entityName}JsonaMapper } from '../inbound/mappers/#kebabCase("${entityName}")-jsona.mapper';
14
+ import { UtilsService } from '@shared/service/utils.service';
15
+ import { JsonApiMeta } from '@shared/models/json-api-meta.entity';
16
+ import { mapJsonApiMeta } from '@shared/mappers/json-api-meta.mapper';
17
+ import { Filter } from '@shared/filters/domain/filter.entity';
18
+
19
+ @Injectable({ providedIn: 'root' })
20
+ export class ${entityName}RepositoryImpl implements ${entityName}RepositoryInterface {
21
+
22
+ private basePath = environment.apiBaseUrl; // URL base de la API
23
+ private resource = '${resourceContext}'; // Recurso al que accedera de la API
24
+ private formatter = new Jsona({
25
+ modelPropertiesMapper: new ${entityName}JsonaMapper()
26
+ });
27
+ #[[
28
+ private apiUrl = `${this.basePath}${this.resource}`; // URL completa de la API
29
+ ]]#
30
+
31
+ private withType(#camelCase("${entityName}"): ${entityName}) {
32
+ return { ...#camelCase("${entityName}"), type: '${resourceContext}' };
33
+ }
34
+
35
+ constructor(
36
+ private http: HttpClient,
37
+ private utils: UtilsService
38
+ ) {}
39
+ #if($hasFileType)
40
+ async create(
41
+ #camelCase("${entityName}"): ${entityName}
42
+ , opts?: { file?: File; field?: string }
43
+ ): Promise<${entityName}> {
44
+ #else
45
+ async create(#camelCase("${entityName}"): ${entityName}): Promise<${entityName}> {
46
+ #end
47
+ const payload = this.formatter.serialize({
48
+ stuff: this.withType(#camelCase("${entityName}"))
49
+ });
50
+ #if($hasFileType)
51
+ if (opts?.file) {
52
+ const formData = new FormData();
53
+ // Parte "data": JSON:API como Blob con su content-type
54
+ formData.append(
55
+ 'data',
56
+ new Blob([JSON.stringify(payload)], { type: 'application/json' })
57
+ );
58
+
59
+ // Parte "file"
60
+ formData.append('file', opts.file);
61
+
62
+ // Parte "field" (opcional, por si el backend lo usa)
63
+ if (opts.field) formData.append('field', opts.field);
64
+
65
+ return await firstValueFrom(this.http.post<any>(this.apiUrl, formData));
66
+ } else {
67
+ return await firstValueFrom(
68
+ this.http.post<any>(
69
+ this.apiUrl,
70
+ payload,
71
+ { headers: { 'Content-Type': 'application/vnd.api+json' } }
72
+ )
73
+ );
74
+ }
75
+ #else
76
+ return await firstValueFrom(
77
+ this.http.post<any>(
78
+ this.apiUrl,
79
+ payload,
80
+ { headers: { 'Content-Type': 'application/vnd.api+json' } }
81
+ )
82
+ );
83
+ #end
84
+ }
85
+
86
+ async delete(id: string): Promise<void> {
87
+ await firstValueFrom(#[[this.http.delete<any>(`${this.apiUrl}/${id}`)]]#);
88
+ }
89
+
90
+ #if($hasFileType)
91
+ async update(
92
+ #camelCase("${entityName}"): ${entityName},
93
+ opts?: { file?: File; field?: string }
94
+ ): Promise<void> {
95
+ #else
96
+ async update(#camelCase("${entityName}"): ${entityName}): Promise<void> {
97
+ #end
98
+ const url = `#[[${this.apiUrl}/${]]##camelCase("${entityName}").id}`;
99
+ const payload = this.formatter.serialize({
100
+ stuff: this.withType(#camelCase("${entityName}"))
101
+ });
102
+ #if($hasFileType)
103
+ if (opts?.file) {
104
+ const formData = new FormData();
105
+ // Parte "data": JSON:API como Blob con su content-type
106
+ formData.append(
107
+ 'data',
108
+ new Blob([JSON.stringify(payload)], { type: 'application/json' })
109
+ );
110
+
111
+ // Parte "file"
112
+ formData.append('file', opts.file);
113
+
114
+ // Parte "field" (opcional, por si el backend lo usa)
115
+ if (opts.field) formData.append('field', opts.field);
116
+
117
+ await firstValueFrom(this.http.put<any>(url, formData));
118
+ } else {
119
+ await firstValueFrom(
120
+ this.http.put<any>(url, payload, {
121
+ headers: { 'Content-Type': 'application/vnd.api+json' }
122
+ })
123
+ );
124
+ }
125
+ #else
126
+ await firstValueFrom(
127
+ this.http.put<any>(
128
+ url,
129
+ payload,
130
+ { headers: { 'Content-Type': 'application/vnd.api+json' } }
131
+ )
132
+ );
133
+ #end
134
+ }
135
+
136
+ async find(id: string): Promise<${entityName} | null> {
137
+ const response = await firstValueFrom(this.http.get<any>(this.apiUrl+"/"+id));
138
+ return this.formatter.deserialize(response) as ${entityName} | null;
139
+ }
140
+
141
+ async search(
142
+ filter?: Filter[],
143
+ include?: string[],
144
+ pagination?: { page: number; limit: number },
145
+ sort?: string
146
+ ): Promise<{data: ${entityName}[], meta: JsonApiMeta}> {
147
+ const params = this.utils.buildSearchParams(filter, include, pagination, sort);
148
+ const response = await firstValueFrom(this.http.get<any>(this.apiUrl, { params }));
149
+ return { data: this.formatter.deserialize(response) as ${entityName}[], meta: mapJsonApiMeta(response) };
150
+ }
151
+ #if($hasFileTypeinNAS)
152
+ async downloadFile(id: number): Promise<Blob> {
153
+ const url = `#[[${this.apiUrl}/${id}/download]]#`;
154
+
155
+ // Creamos el observable pero no nos suscribimos aún
156
+ const request$ = this.http.get(url, { responseType: 'blob' });
157
+
158
+ // Convertimos el observable a promesa y esperamos el último valor (que es la respuesta HTTP)
159
+ return await firstValueFrom(request$);
160
+ }
161
+ #end
162
+ }
@@ -0,0 +1,3 @@
1
+ #foreach( $entity in $project.entities )
2
+ $entity.name /
3
+ #end