@devstroupe/devkit-cli 1.0.0

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 (170) hide show
  1. package/README.md +40 -0
  2. package/dist/boilerplates/angular-template/.dockerignore +4 -0
  3. package/dist/boilerplates/angular-template/.postcssrc.json +5 -0
  4. package/dist/boilerplates/angular-template/Dockerfile +14 -0
  5. package/dist/boilerplates/angular-template/angular.json +85 -0
  6. package/dist/boilerplates/angular-template/components.json +5 -0
  7. package/dist/boilerplates/angular-template/framework.code-workspace +7 -0
  8. package/dist/boilerplates/angular-template/nginx.conf +23 -0
  9. package/dist/boilerplates/angular-template/node_modules/.bin/browserslist +21 -0
  10. package/dist/boilerplates/angular-template/node_modules/.bin/jiti +21 -0
  11. package/dist/boilerplates/angular-template/node_modules/.bin/lessc +21 -0
  12. package/dist/boilerplates/angular-template/node_modules/.bin/ng +21 -0
  13. package/dist/boilerplates/angular-template/node_modules/.bin/ng-xi18n +21 -0
  14. package/dist/boilerplates/angular-template/node_modules/.bin/ngc +21 -0
  15. package/dist/boilerplates/angular-template/node_modules/.bin/sass +21 -0
  16. package/dist/boilerplates/angular-template/node_modules/.bin/terser +21 -0
  17. package/dist/boilerplates/angular-template/node_modules/.bin/tsc +21 -0
  18. package/dist/boilerplates/angular-template/node_modules/.bin/tsserver +21 -0
  19. package/dist/boilerplates/angular-template/node_modules/.bin/vite +21 -0
  20. package/dist/boilerplates/angular-template/node_modules/.bin/vitest +21 -0
  21. package/dist/boilerplates/angular-template/node_modules/.bin/yaml +21 -0
  22. package/dist/boilerplates/angular-template/package.json +47 -0
  23. package/dist/boilerplates/angular-template/postcss.config.js +5 -0
  24. package/dist/boilerplates/angular-template/proxy.conf.json +7 -0
  25. package/dist/boilerplates/angular-template/src/app/app.component.html +3 -0
  26. package/dist/boilerplates/angular-template/src/app/app.component.ts +12 -0
  27. package/dist/boilerplates/angular-template/src/app/app.config.ts +59 -0
  28. package/dist/boilerplates/angular-template/src/app/app.entity-routes.ts +4 -0
  29. package/dist/boilerplates/angular-template/src/app/app.routes.ts +25 -0
  30. package/dist/boilerplates/angular-template/src/app/core/guards/auth.guard.ts +16 -0
  31. package/dist/boilerplates/angular-template/src/app/core/services/auth.service.ts +98 -0
  32. package/dist/boilerplates/angular-template/src/app/modules/auth/login/login.component.html +51 -0
  33. package/dist/boilerplates/angular-template/src/app/modules/auth/login/login.component.ts +47 -0
  34. package/dist/boilerplates/angular-template/src/app/modules/auth/register/register.component.html +59 -0
  35. package/dist/boilerplates/angular-template/src/app/modules/auth/register/register.component.ts +47 -0
  36. package/dist/boilerplates/angular-template/src/app/modules/dashboard/dashboard.component.html +14 -0
  37. package/dist/boilerplates/angular-template/src/app/modules/dashboard/dashboard.component.ts +23 -0
  38. package/dist/boilerplates/angular-template/src/app/shared/interceptors/tenant.interceptor.ts +25 -0
  39. package/dist/boilerplates/angular-template/src/index.html +64 -0
  40. package/dist/boilerplates/angular-template/src/main.ts +6 -0
  41. package/dist/boilerplates/angular-template/src/styles.css +9 -0
  42. package/dist/boilerplates/angular-template/tsconfig.json +36 -0
  43. package/dist/boilerplates/nest-template/Dockerfile +16 -0
  44. package/dist/boilerplates/nest-template/node_modules/.bin/acorn +21 -0
  45. package/dist/boilerplates/nest-template/node_modules/.bin/nest +21 -0
  46. package/dist/boilerplates/nest-template/node_modules/.bin/prettier +21 -0
  47. package/dist/boilerplates/nest-template/node_modules/.bin/tsc +21 -0
  48. package/dist/boilerplates/nest-template/node_modules/.bin/tsserver +21 -0
  49. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm +21 -0
  50. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm-ts-node-commonjs +21 -0
  51. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm-ts-node-esm +21 -0
  52. package/dist/boilerplates/nest-template/node_modules/.bin/webpack +21 -0
  53. package/dist/boilerplates/nest-template/package.json +43 -0
  54. package/dist/boilerplates/nest-template/src/app.module.ts +24 -0
  55. package/dist/boilerplates/nest-template/src/database/data-source.ts +16 -0
  56. package/dist/boilerplates/nest-template/src/database/migrations/1700000000000-create-users.ts +26 -0
  57. package/dist/boilerplates/nest-template/src/main.ts +46 -0
  58. package/dist/boilerplates/nest-template/src/modules/auth/auth.controller.ts +34 -0
  59. package/dist/boilerplates/nest-template/src/modules/auth/auth.module.ts +22 -0
  60. package/dist/boilerplates/nest-template/src/modules/auth/auth.service.ts +57 -0
  61. package/dist/boilerplates/nest-template/src/modules/auth/current-user.decorator.ts +8 -0
  62. package/dist/boilerplates/nest-template/src/modules/auth/jwt-auth.guard.ts +31 -0
  63. package/dist/boilerplates/nest-template/src/modules/auth/roles.decorator.ts +4 -0
  64. package/dist/boilerplates/nest-template/src/modules/auth/roles.guard.ts +24 -0
  65. package/dist/boilerplates/nest-template/src/modules/user/database-seed.service.ts +47 -0
  66. package/dist/boilerplates/nest-template/src/modules/user/domain/user.repository.ts +9 -0
  67. package/dist/boilerplates/nest-template/src/modules/user/domain/user.ts +9 -0
  68. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.orm-entity.ts +31 -0
  69. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.repository.adapter.ts +53 -0
  70. package/dist/boilerplates/nest-template/src/modules/user/service/user.service.ts +44 -0
  71. package/dist/boilerplates/nest-template/src/modules/user/user.module.ts +20 -0
  72. package/dist/boilerplates/nest-template/tsconfig.build.json +4 -0
  73. package/dist/boilerplates/nest-template/tsconfig.json +21 -0
  74. package/dist/index.d.ts +2 -0
  75. package/dist/index.js +1967 -0
  76. package/dist/migrations/sort-entities.d.ts +2 -0
  77. package/dist/migrations/sort-entities.js +30 -0
  78. package/dist/rules/linter-rules.d.ts +12 -0
  79. package/dist/rules/linter-rules.js +338 -0
  80. package/dist/rules/linter-rules.test.d.ts +1 -0
  81. package/dist/rules/linter-rules.test.js +214 -0
  82. package/dist/templates/angular/dialog-handler.template.d.ts +2 -0
  83. package/dist/templates/angular/dialog-handler.template.js +49 -0
  84. package/dist/templates/angular/form.template.d.ts +3 -0
  85. package/dist/templates/angular/form.template.js +453 -0
  86. package/dist/templates/angular/index.d.ts +4 -0
  87. package/dist/templates/angular/index.js +20 -0
  88. package/dist/templates/angular/list.template.d.ts +3 -0
  89. package/dist/templates/angular/list.template.js +213 -0
  90. package/dist/templates/angular/service.template.d.ts +1 -0
  91. package/dist/templates/angular/service.template.js +20 -0
  92. package/dist/templates/cli-templates.d.ts +2 -0
  93. package/dist/templates/cli-templates.js +18 -0
  94. package/dist/templates/nest/crud.templates.d.ts +9 -0
  95. package/dist/templates/nest/crud.templates.js +362 -0
  96. package/dist/templates/nest/index.d.ts +3 -0
  97. package/dist/templates/nest/index.js +19 -0
  98. package/dist/templates/nest/microservice.templates.d.ts +4 -0
  99. package/dist/templates/nest/microservice.templates.js +157 -0
  100. package/dist/templates/nest/migration.template.d.ts +3 -0
  101. package/dist/templates/nest/migration.template.js +127 -0
  102. package/dist/templates/relationship-templates.test.d.ts +1 -0
  103. package/dist/templates/relationship-templates.test.js +181 -0
  104. package/dist/templates/shared/names.d.ts +3 -0
  105. package/dist/templates/shared/names.js +14 -0
  106. package/dist/templates/shared/relationships.d.ts +27 -0
  107. package/dist/templates/shared/relationships.js +96 -0
  108. package/dist/templates/ui/components/avatar.template.d.ts +3 -0
  109. package/dist/templates/ui/components/avatar.template.js +66 -0
  110. package/dist/templates/ui/components/badge.template.d.ts +3 -0
  111. package/dist/templates/ui/components/badge.template.js +27 -0
  112. package/dist/templates/ui/components/button.template.d.ts +5 -0
  113. package/dist/templates/ui/components/button.template.js +64 -0
  114. package/dist/templates/ui/components/card-list.template.d.ts +5 -0
  115. package/dist/templates/ui/components/card-list.template.js +79 -0
  116. package/dist/templates/ui/components/dialog.template.d.ts +5 -0
  117. package/dist/templates/ui/components/dialog.template.js +51 -0
  118. package/dist/templates/ui/components/filter.template.d.ts +4 -0
  119. package/dist/templates/ui/components/filter.template.js +218 -0
  120. package/dist/templates/ui/components/index.d.ts +10 -0
  121. package/dist/templates/ui/components/index.js +26 -0
  122. package/dist/templates/ui/components/input.template.d.ts +4 -0
  123. package/dist/templates/ui/components/input.template.js +76 -0
  124. package/dist/templates/ui/components/select.template.d.ts +4 -0
  125. package/dist/templates/ui/components/select.template.js +176 -0
  126. package/dist/templates/ui/components/simple-list.template.d.ts +5 -0
  127. package/dist/templates/ui/components/simple-list.template.js +89 -0
  128. package/dist/templates/ui/components/table.template.d.ts +5 -0
  129. package/dist/templates/ui/components/table.template.js +112 -0
  130. package/dist/templates/ui/index.d.ts +9 -0
  131. package/dist/templates/ui/index.js +25 -0
  132. package/dist/templates/ui/layout/header.template.d.ts +5 -0
  133. package/dist/templates/ui/layout/header.template.js +236 -0
  134. package/dist/templates/ui/layout/index.d.ts +4 -0
  135. package/dist/templates/ui/layout/index.js +20 -0
  136. package/dist/templates/ui/layout/main-layout.template.d.ts +5 -0
  137. package/dist/templates/ui/layout/main-layout.template.js +126 -0
  138. package/dist/templates/ui/layout/shell.template.d.ts +5 -0
  139. package/dist/templates/ui/layout/shell.template.js +76 -0
  140. package/dist/templates/ui/layout/sidebar.template.d.ts +5 -0
  141. package/dist/templates/ui/layout/sidebar.template.js +412 -0
  142. package/dist/templates/ui/playground.template.d.ts +5 -0
  143. package/dist/templates/ui/playground.template.js +570 -0
  144. package/dist/templates/ui/readme.template.d.ts +1 -0
  145. package/dist/templates/ui/readme.template.js +23 -0
  146. package/dist/templates/ui/shared/colors.d.ts +1 -0
  147. package/dist/templates/ui/shared/colors.js +31 -0
  148. package/dist/templates/ui/shared/profile-component.template.d.ts +5 -0
  149. package/dist/templates/ui/shared/profile-component.template.js +403 -0
  150. package/dist/templates/ui/shared/profile-service.template.d.ts +1 -0
  151. package/dist/templates/ui/shared/profile-service.template.js +44 -0
  152. package/dist/templates/ui/shared/theme-service.template.d.ts +1 -0
  153. package/dist/templates/ui/shared/theme-service.template.js +47 -0
  154. package/dist/templates/ui/spartan/badge-directive.template.d.ts +3 -0
  155. package/dist/templates/ui/spartan/badge-directive.template.js +50 -0
  156. package/dist/templates/ui/spartan/button-directive.template.d.ts +3 -0
  157. package/dist/templates/ui/spartan/button-directive.template.js +82 -0
  158. package/dist/templates/ui/spartan/button-token.template.d.ts +3 -0
  159. package/dist/templates/ui/spartan/button-token.template.js +31 -0
  160. package/dist/templates/ui/spartan/hlm-core.template.d.ts +3 -0
  161. package/dist/templates/ui/spartan/hlm-core.template.js +322 -0
  162. package/dist/templates/ui/spartan/index.d.ts +5 -0
  163. package/dist/templates/ui/spartan/index.js +21 -0
  164. package/dist/templates/ui/spartan/input-directive.template.d.ts +3 -0
  165. package/dist/templates/ui/spartan/input-directive.template.js +31 -0
  166. package/dist/templates/ui/theme-css.template.d.ts +7 -0
  167. package/dist/templates/ui/theme-css.template.js +210 -0
  168. package/dist/templates/ui-templates.d.ts +1 -0
  169. package/dist/templates/ui-templates.js +17 -0
  170. package/package.json +50 -0
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitAvatarTemplate = devkitAvatarTemplate;
4
+ function devkitAvatarTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, OnInit, signal } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+
9
+ @Component({
10
+ selector: 'devkit-avatar',
11
+ standalone: true,
12
+ imports: [CommonModule],
13
+ template: \`
14
+ <div
15
+ [class]="'relative flex shrink-0 overflow-hidden rounded-full border border-border bg-muted ' + sizeClasses[size] + ' ' + class"
16
+ >
17
+ <img
18
+ *ngIf="src && !hasError()"
19
+ [src]="src"
20
+ [alt]="alt"
21
+ class="aspect-square h-full w-full object-cover"
22
+ (error)="onError()"
23
+ />
24
+ <div
25
+ *ngIf="!src || hasError()"
26
+ class="flex h-full w-full items-center justify-center rounded-full bg-muted font-medium text-muted-foreground"
27
+ >
28
+ {{ initials }}
29
+ </div>
30
+ </div>
31
+ \`
32
+ })
33
+ export class DevkitAvatarComponent implements OnInit {
34
+ @Input() src?: string;
35
+ @Input() alt = '';
36
+ @Input() name = '';
37
+ @Input() size: 'sm' | 'md' | 'lg' = 'md';
38
+ @Input() class = '';
39
+
40
+ protected readonly hasError = signal(false);
41
+
42
+ sizeClasses = {
43
+ sm: 'h-8 w-8 text-xs',
44
+ md: 'h-10 w-10 text-sm',
45
+ lg: 'h-16 w-16 text-xl'
46
+ };
47
+
48
+ get initials(): string {
49
+ if (!this.name) return '';
50
+ const parts = this.name.split(' ');
51
+ if (parts.length === 1) return parts[0].substring(0, 2).toUpperCase();
52
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
53
+ }
54
+
55
+ ngOnInit(): void {
56
+ this.hasError.set(false);
57
+ }
58
+
59
+ onError(): void {
60
+ this.hasError.set(true);
61
+ }
62
+ }
63
+ `
64
+ };
65
+ }
66
+ // 21. Template da página de Playground
@@ -0,0 +1,3 @@
1
+ export declare function devkitBadgeTemplate(): {
2
+ ts: string;
3
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitBadgeTemplate = devkitBadgeTemplate;
4
+ function devkitBadgeTemplate() {
5
+ return {
6
+ ts: `import { Component, Input } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { HlmBadge } from '@spartan-ng/helm/badge';
9
+
10
+ @Component({
11
+ selector: 'devkit-badge',
12
+ standalone: true,
13
+ imports: [CommonModule, HlmBadge],
14
+ template: \`
15
+ <span hlmBadge [variant]="variant" [class]="class">
16
+ <ng-content></ng-content>
17
+ </span>
18
+ \`
19
+ })
20
+ export class DevkitBadgeComponent {
21
+ @Input() variant: 'default' | 'secondary' | 'destructive' | 'outline' = 'default';
22
+ @Input() class = '';
23
+ }
24
+ `
25
+ };
26
+ }
27
+ // 20. Template do devkit-avatar
@@ -0,0 +1,5 @@
1
+ export declare function devkitButtonTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitButtonTemplate = devkitButtonTemplate;
4
+ function devkitButtonTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, Output, EventEmitter } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { HlmButton } from '@spartan-ng/helm/button';
9
+
10
+ @Component({
11
+ selector: 'devkit-button',
12
+ standalone: true,
13
+ imports: [CommonModule, HlmButton],
14
+ templateUrl: './button.component.html',
15
+ styleUrls: ['./button.component.css']
16
+ })
17
+ export class DevkitButtonComponent {
18
+ @Input() variant: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' | 'primary' | 'danger' = 'default';
19
+ @Input() size: 'default' | 'sm' | 'md' | 'lg' | 'icon' = 'default';
20
+ @Input() disabled = false;
21
+ @Input() loading = false;
22
+ @Input() type: 'button' | 'submit' | 'reset' = 'button';
23
+ @Input() fullWidth = false;
24
+
25
+ @Output() btnClick = new EventEmitter<MouseEvent>();
26
+
27
+ get resolvedVariant(): 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' {
28
+ if (this.variant === 'primary') return 'default';
29
+ if (this.variant === 'danger') return 'destructive';
30
+ return this.variant;
31
+ }
32
+
33
+ get resolvedSize(): 'default' | 'sm' | 'lg' | 'icon' {
34
+ if (this.size === 'md') return 'default';
35
+ return this.size;
36
+ }
37
+
38
+ onClick(event: MouseEvent): void {
39
+ if (!this.disabled && !this.loading) {
40
+ this.btnClick.emit(event);
41
+ }
42
+ }
43
+ }
44
+ `,
45
+ html: `<button
46
+ hlmBtn
47
+ [variant]="resolvedVariant"
48
+ [size]="resolvedSize"
49
+ [type]="type"
50
+ [disabled]="disabled || loading"
51
+ [class.w-full]="fullWidth"
52
+ (click)="onClick($event)"
53
+ >
54
+ <span *ngIf="loading" class="mr-2 inline-block w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin"></span>
55
+ <ng-content></ng-content>
56
+ </button>
57
+ `,
58
+ css: `:host {
59
+ display: inline-flex;
60
+ }
61
+ `
62
+ };
63
+ }
64
+ // 3. Template do devkit-input
@@ -0,0 +1,5 @@
1
+ export declare function devkitCardListTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitCardListTemplate = devkitCardListTemplate;
4
+ function devkitCardListTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, Output, EventEmitter, TemplateRef } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { HlmCardImports } from '@spartan-ng/helm/card';
9
+
10
+ export interface ITableColumn {
11
+ key: string;
12
+ label: string;
13
+ sortable?: boolean;
14
+ }
15
+
16
+ @Component({
17
+ selector: 'devkit-card-list',
18
+ standalone: true,
19
+ imports: [CommonModule, HlmCardImports],
20
+ templateUrl: './card-list.component.html',
21
+ styleUrls: ['./card-list.component.css']
22
+ })
23
+ export class DevkitCardListComponent {
24
+ @Input() columns: ITableColumn[] = [];
25
+ @Input() items: any[] = [];
26
+ @Input() customTemplates?: { [columnKey: string]: TemplateRef<any> };
27
+
28
+ @Output() rowClick = new EventEmitter<any>();
29
+
30
+ getCellValue(item: any, key: string): any {
31
+ if (!key) return '';
32
+ if (key.includes('.')) {
33
+ const value = key.split('.').reduce((acc, part) => {
34
+ if (Array.isArray(acc)) return acc.map(entry => entry?.[part]).filter(Boolean);
35
+ return acc && acc[part];
36
+ }, item);
37
+ return Array.isArray(value) ? value.join(', ') : value || '';
38
+ }
39
+ return item[key] !== undefined ? item[key] : '';
40
+ }
41
+
42
+ getCardTitle(item: any): string {
43
+ if (item.name) return item.name;
44
+ if (item.title) return item.title;
45
+ if (item.label) return item.label;
46
+ const nonIdCol = this.columns.find(c => c.key !== 'id' && c.key !== 'actions');
47
+ return nonIdCol ? this.getCellValue(item, nonIdCol.key) : '';
48
+ }
49
+ }
50
+ `,
51
+ html: `<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
52
+ <div *ngFor="let item of items; let index = index" hlmCard (click)="rowClick.emit(item)" class="p-5 transition-colors hover:bg-muted/50 cursor-pointer">
53
+ <div class="flex flex-col space-y-3">
54
+ <h3 class="text-lg font-bold tracking-tight text-card-foreground">
55
+ #{{ item.id }} - {{ getCardTitle(item) }}
56
+ </h3>
57
+ <div class="flex flex-col space-y-2 border-t border-border pt-3">
58
+ <div *ngFor="let col of columns" class="flex justify-between text-sm" [class.hidden]="col.key === 'id' || col.key === 'actions'">
59
+ <span class="font-medium text-muted-foreground">{{ col.label }}:</span>
60
+ <span class="text-card-foreground">{{ getCellValue(item, col.key) }}</span>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ <div *ngIf="customTemplates && customTemplates['actions']" class="mt-5 pt-3 border-t border-border flex justify-end">
65
+ <ng-container *ngTemplateOutlet="customTemplates['actions']; context: { $implicit: item, index: index }"></ng-container>
66
+ </div>
67
+ </div>
68
+ <div *ngIf="items.length === 0" class="col-span-full text-center py-10 text-sm text-muted-foreground">
69
+ Nenhum registro encontrado.
70
+ </div>
71
+ </div>
72
+ `,
73
+ css: `:host {
74
+ display: block;
75
+ }
76
+ `
77
+ };
78
+ }
79
+ // 8. Template do devkit-simple-list
@@ -0,0 +1,5 @@
1
+ export declare function devkitDialogTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitDialogTemplate = devkitDialogTemplate;
4
+ function devkitDialogTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, Output, EventEmitter } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { HlmDialogImports } from '@spartan-ng/helm/dialog';
9
+
10
+ @Component({
11
+ selector: 'devkit-dialog',
12
+ standalone: true,
13
+ imports: [CommonModule, HlmDialogImports],
14
+ templateUrl: './dialog.component.html',
15
+ styleUrls: ['./dialog.component.css']
16
+ })
17
+ export class DevkitDialogComponent {
18
+ @Input() isOpen = false;
19
+ @Input() closeOnBackdrop = true;
20
+ @Input() size: 'sm' | 'md' | 'lg' | 'xl' = 'lg';
21
+ @Output() close = new EventEmitter<void>();
22
+
23
+ closeDialog(): void {
24
+ this.close.emit();
25
+ }
26
+
27
+ get maxWidthClass(): string {
28
+ return {
29
+ sm: 'max-w-sm',
30
+ md: 'max-w-md',
31
+ lg: 'max-w-lg',
32
+ xl: 'max-w-5xl'
33
+ }[this.size];
34
+ }
35
+ }
36
+ `,
37
+ html: `<hlm-dialog
38
+ [state]="isOpen ? 'open' : 'closed'"
39
+ [closeOnOutsidePointerEvents]="closeOnBackdrop"
40
+ [disableClose]="!closeOnBackdrop"
41
+ (closed)="closeDialog()"
42
+ >
43
+ <hlm-dialog-content *hlmDialogPortal [class]="maxWidthClass">
44
+ <ng-content></ng-content>
45
+ </hlm-dialog-content>
46
+ </hlm-dialog>
47
+ `,
48
+ css: ``
49
+ };
50
+ }
51
+ // 10. Template do devkit-shell
@@ -0,0 +1,4 @@
1
+ export declare function devkitFilterTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ };
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitFilterTemplate = devkitFilterTemplate;
4
+ function devkitFilterTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { FormsModule } from '@angular/forms';
9
+ import { HlmCardImports } from '@spartan-ng/helm/card';
10
+ import { HlmPopoverImports } from '@spartan-ng/helm/popover';
11
+ import { HlmDialogImports } from '@spartan-ng/helm/dialog';
12
+ import { HlmButton } from '@spartan-ng/helm/button';
13
+ import { DevkitInputComponent } from '../input/input.component';
14
+ import { DevkitSelectComponent, DevkitSelectOption } from '../select/select.component';
15
+ import { DevkitButtonComponent } from '../button/button.component';
16
+ import { NgIconComponent } from '@ng-icons/core';
17
+
18
+ export interface FilterOption {
19
+ label: string;
20
+ value: any;
21
+ }
22
+
23
+ export interface FilterItemConfig {
24
+ key: string;
25
+ label: string;
26
+ type: 'text' | 'select' | 'datepicker' | 'boolean';
27
+ options?: FilterOption[];
28
+ col?: string;
29
+ searchable?: boolean;
30
+ loading?: boolean;
31
+ hasMore?: boolean;
32
+ onSearch?: (search: string) => void;
33
+ onLoadMore?: () => void;
34
+ }
35
+
36
+ @Component({
37
+ selector: 'devkit-filter',
38
+ standalone: true,
39
+ imports: [
40
+ CommonModule,
41
+ FormsModule,
42
+ HlmCardImports,
43
+ HlmPopoverImports,
44
+ HlmDialogImports,
45
+ HlmButton,
46
+ DevkitInputComponent,
47
+ DevkitSelectComponent,
48
+ DevkitButtonComponent,
49
+ NgIconComponent
50
+ ],
51
+ templateUrl: './filter.component.html'
52
+ })
53
+ export class DevkitFilterComponent implements OnInit {
54
+ @Input() config: FilterItemConfig[] = [];
55
+ @Input() initialValues: any = {};
56
+ @Input() displayMode: 'inline' | 'popover' | 'dialog' = 'popover';
57
+
58
+ @Output() filterApplied = new EventEmitter<any>();
59
+
60
+ public filterValues: any = {};
61
+
62
+ ngOnInit(): void {
63
+ this.resetValues();
64
+ }
65
+
66
+ resetValues(): void {
67
+ this.filterValues = { ...this.initialValues };
68
+ this.config.forEach((item) => {
69
+ if (this.filterValues[item.key] === undefined) {
70
+ this.filterValues[item.key] = item.type === 'select' ? (item.options?.[0]?.value ?? null) : null;
71
+ }
72
+ });
73
+ }
74
+
75
+ clearFilters(): void {
76
+ this.filterValues = {};
77
+ this.resetValues();
78
+ this.filterApplied.emit(this.filterValues);
79
+ }
80
+
81
+ apply(): void {
82
+ this.filterApplied.emit(this.filterValues);
83
+ }
84
+
85
+ getActiveFiltersCount(): number {
86
+ let count = 0;
87
+ for (const key of Object.keys(this.filterValues)) {
88
+ const val = this.filterValues[key];
89
+ if (val !== null && val !== undefined && val !== '') {
90
+ count++;
91
+ }
92
+ }
93
+ return count;
94
+ }
95
+ }
96
+ `,
97
+ html: `<!-- MODO INLINE (PADRÃO) -->
98
+ <div *ngIf="displayMode === 'inline'" hlmCard class="p-4 w-full flex flex-col space-y-4">
99
+ <ng-container *ngTemplateOutlet="fieldsGridTemplate"></ng-container>
100
+ <div class="flex justify-end space-x-2">
101
+ <devkit-button variant="secondary" (btnClick)="clearFilters()">
102
+ <ng-icon name="lucideRotateCcw" class="mr-1.5 size-4"></ng-icon>
103
+ Limpar
104
+ </devkit-button>
105
+ <devkit-button variant="primary" (btnClick)="apply()">
106
+ <ng-icon name="lucideSlidersHorizontal" class="mr-1.5 size-4"></ng-icon>
107
+ Filtrar
108
+ </devkit-button>
109
+ </div>
110
+ </div>
111
+
112
+ <!-- MODO POPOVER OVERLAY -->
113
+ <hlm-popover *ngIf="displayMode === 'popover'">
114
+ <button hlmBtn variant="outline" hlmPopoverTrigger class="flex items-center space-x-2">
115
+ <ng-icon name="lucideSlidersHorizontal" class="mr-1.5 size-4"></ng-icon>
116
+ <span>Filtros</span>
117
+ <span *ngIf="getActiveFiltersCount() > 0" class="ml-1.5 rounded-full bg-primary text-primary-foreground px-1.5 py-0.5 text-xs font-bold leading-none">
118
+ {{ getActiveFiltersCount() }}
119
+ </span>
120
+ </button>
121
+ <hlm-popover-content *hlmPopoverPortal class="w-80 p-4 flex flex-col space-y-4">
122
+ <div class="flex flex-col space-y-3">
123
+ <ng-container *ngTemplateOutlet="fieldsListTemplate"></ng-container>
124
+ </div>
125
+ <div class="flex justify-end space-x-2 border-t border-border pt-3">
126
+ <button hlmBtn variant="ghost" size="sm" (click)="clearFilters()">Limpar</button>
127
+ <button hlmBtn size="sm" (click)="apply()">Filtrar</button>
128
+ </div>
129
+ </hlm-popover-content>
130
+ </hlm-popover>
131
+
132
+ <!-- MODO DIALOG MODAL -->
133
+ <hlm-dialog *ngIf="displayMode === 'dialog'">
134
+ <button hlmBtn variant="outline" hlmDialogTrigger class="flex items-center space-x-2">
135
+ <ng-icon name="lucideSlidersHorizontal" class="mr-1.5 size-4"></ng-icon>
136
+ <span>Filtros</span>
137
+ <span *ngIf="getActiveFiltersCount() > 0" class="ml-1.5 rounded-full bg-primary text-primary-foreground px-1.5 py-0.5 text-xs font-bold leading-none">
138
+ {{ getActiveFiltersCount() }}
139
+ </span>
140
+ </button>
141
+ <hlm-dialog-content *hlmDialogPortal class="sm:max-w-lg p-6">
142
+ <hlm-dialog-header>
143
+ <h3 hlmDialogTitle>Filtrar registros</h3>
144
+ <p hlmDialogDescription>Selecione as opções de filtros desejadas para refinar os resultados.</p>
145
+ </hlm-dialog-header>
146
+ <div class="py-4">
147
+ <ng-container *ngTemplateOutlet="fieldsGridTemplate"></ng-container>
148
+ </div>
149
+ <hlm-dialog-footer class="flex justify-end space-x-2 pt-4 border-t border-border">
150
+ <button hlmBtn variant="ghost" hlmDialogClose (click)="clearFilters()">Limpar</button>
151
+ <button hlmBtn hlmDialogClose (click)="apply()">Filtrar</button>
152
+ </hlm-dialog-footer>
153
+ </hlm-dialog-content>
154
+ </hlm-dialog>
155
+
156
+ <!-- Template Reutilizável: Grid de campos (usado no Inline e Dialog) -->
157
+ <ng-template #fieldsGridTemplate>
158
+ <div class="grid grid-cols-12 gap-4">
159
+ <div *ngFor="let item of config" [class]="item.col || 'col-span-12 md:col-span-4'" class="flex flex-col space-y-1">
160
+ <ng-container *ngTemplateOutlet="fieldTemplate; context: { item: item }"></ng-container>
161
+ </div>
162
+ </div>
163
+ </ng-template>
164
+
165
+ <!-- Template Reutilizável: Lista vertical de campos (usado no Popover) -->
166
+ <ng-template #fieldsListTemplate>
167
+ <div *ngFor="let item of config" class="flex flex-col space-y-1 w-full">
168
+ <ng-container *ngTemplateOutlet="fieldTemplate; context: { item: item }"></ng-container>
169
+ </div>
170
+ </ng-template>
171
+
172
+ <!-- Template Reutilizável: Renderizador de Campo Individual -->
173
+ <ng-template #fieldTemplate let-item="item">
174
+ <!-- Tipo Text -->
175
+ <devkit-input
176
+ *ngIf="item.type === 'text'"
177
+ [label]="item.label"
178
+ [placeholder]="item.label"
179
+ [(ngModel)]="filterValues[item.key]"
180
+ ></devkit-input>
181
+
182
+ <!-- Tipo Select -->
183
+ <devkit-select
184
+ *ngIf="item.type === 'select'"
185
+ [label]="item.label"
186
+ [options]="item.options || []"
187
+ [searchable]="item.searchable || false"
188
+ [loading]="item.loading || false"
189
+ [hasMore]="item.hasMore || false"
190
+ (searchChange)="item.onSearch?.($event)"
191
+ (loadMore)="item.onLoadMore?.()"
192
+ [(ngModel)]="filterValues[item.key]"
193
+ ></devkit-select>
194
+
195
+ <!-- Tipo Boolean -->
196
+ <devkit-select
197
+ *ngIf="item.type === 'boolean'"
198
+ [label]="item.label"
199
+ [options]="[
200
+ { label: 'Todos', value: null },
201
+ { label: 'Sim / Ativo', value: true },
202
+ { label: 'Não / Inativo', value: false }
203
+ ]"
204
+ [(ngModel)]="filterValues[item.key]"
205
+ ></devkit-select>
206
+
207
+ <!-- Tipo Datepicker -->
208
+ <devkit-input
209
+ *ngIf="item.type === 'datepicker'"
210
+ type="date"
211
+ [label]="item.label"
212
+ [(ngModel)]="filterValues[item.key]"
213
+ ></devkit-input>
214
+ </ng-template>
215
+ `
216
+ };
217
+ }
218
+ // 7. Template do devkit-card-list
@@ -0,0 +1,10 @@
1
+ export * from './button.template';
2
+ export * from './input.template';
3
+ export * from './select.template';
4
+ export * from './table.template';
5
+ export * from './filter.template';
6
+ export * from './card-list.template';
7
+ export * from './simple-list.template';
8
+ export * from './dialog.template';
9
+ export * from './badge.template';
10
+ export * from './avatar.template';
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./button.template"), exports);
18
+ __exportStar(require("./input.template"), exports);
19
+ __exportStar(require("./select.template"), exports);
20
+ __exportStar(require("./table.template"), exports);
21
+ __exportStar(require("./filter.template"), exports);
22
+ __exportStar(require("./card-list.template"), exports);
23
+ __exportStar(require("./simple-list.template"), exports);
24
+ __exportStar(require("./dialog.template"), exports);
25
+ __exportStar(require("./badge.template"), exports);
26
+ __exportStar(require("./avatar.template"), exports);
@@ -0,0 +1,4 @@
1
+ export declare function devkitInputTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitInputTemplate = devkitInputTemplate;
4
+ function devkitInputTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, forwardRef } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
9
+ import { HlmInput } from '@spartan-ng/helm/input';
10
+
11
+ @Component({
12
+ selector: 'devkit-input',
13
+ standalone: true,
14
+ imports: [CommonModule, FormsModule, HlmInput],
15
+ templateUrl: './input.component.html',
16
+ providers: [
17
+ {
18
+ provide: NG_VALUE_ACCESSOR,
19
+ useExisting: forwardRef(() => DevkitInputComponent),
20
+ multi: true
21
+ }
22
+ ]
23
+ })
24
+ export class DevkitInputComponent implements ControlValueAccessor {
25
+ @Input() label = '';
26
+ @Input() placeholder = '';
27
+ @Input() type = 'text';
28
+ @Input() required = false;
29
+ @Input() disabled = false;
30
+
31
+ value: string | number = '';
32
+
33
+ onChange: any = () => {};
34
+ onTouched: any = () => {};
35
+
36
+ writeValue(value: any): void {
37
+ this.value = value || '';
38
+ }
39
+
40
+ registerOnChange(fn: any): void {
41
+ this.onChange = fn;
42
+ }
43
+
44
+ registerOnTouched(fn: any): void {
45
+ this.onTouched = fn;
46
+ }
47
+
48
+ setDisabledState(isDisabled: boolean): void {
49
+ this.disabled = isDisabled;
50
+ }
51
+
52
+ onInput(event: Event): void {
53
+ const val = (event.target as HTMLInputElement).value;
54
+ this.value = val;
55
+ this.onChange(val);
56
+ }
57
+ }
58
+ `,
59
+ html: `<div class="flex flex-col space-y-1.5 w-full">
60
+ <label *ngIf="label" class="text-xs font-semibold text-muted-foreground">
61
+ {{ label }}<span *ngIf="required" class="text-destructive ml-0.5">*</span>
62
+ </label>
63
+ <input
64
+ hlmInput
65
+ [type]="type"
66
+ [value]="value"
67
+ [placeholder]="placeholder"
68
+ [disabled]="disabled"
69
+ (input)="onInput($event)"
70
+ (blur)="onTouched()"
71
+ />
72
+ </div>
73
+ `
74
+ };
75
+ }
76
+ // 4. Template do devkit-select
@@ -0,0 +1,4 @@
1
+ export declare function devkitSelectTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ };