@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,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitSelectTemplate = devkitSelectTemplate;
4
+ function devkitSelectTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, Output, EventEmitter, OnDestroy, forwardRef } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
9
+ import { HlmSelectImports } from '@spartan-ng/helm/select';
10
+ import { HlmInput } from '@spartan-ng/helm/input';
11
+ import { HlmButton } from '@spartan-ng/helm/button';
12
+
13
+ export interface DevkitSelectOption {
14
+ label: string;
15
+ value: any;
16
+ }
17
+
18
+ @Component({
19
+ selector: 'devkit-select',
20
+ standalone: true,
21
+ imports: [CommonModule, FormsModule, HlmSelectImports, HlmInput, HlmButton],
22
+ templateUrl: './select.component.html',
23
+ providers: [
24
+ {
25
+ provide: NG_VALUE_ACCESSOR,
26
+ useExisting: forwardRef(() => DevkitSelectComponent),
27
+ multi: true
28
+ }
29
+ ]
30
+ })
31
+ export class DevkitSelectComponent implements ControlValueAccessor, OnDestroy {
32
+ @Input() label = '';
33
+ @Input() placeholder = 'Selecione...';
34
+ @Input() options: DevkitSelectOption[] = [];
35
+ @Input() required = false;
36
+ @Input() disabled = false;
37
+ @Input() multiple = false;
38
+ @Input() searchable = false;
39
+ @Input() loading = false;
40
+ @Input() hasMore = false;
41
+
42
+ @Output() searchChange = new EventEmitter<string>();
43
+ @Output() loadMore = new EventEmitter<void>();
44
+
45
+ value: any = null;
46
+ searchTerm = '';
47
+ private searchTimer?: ReturnType<typeof setTimeout>;
48
+
49
+ onChange: any = () => {};
50
+ onTouched: any = () => {};
51
+ itemToString = (value: any): string => this.getSelectedLabel(value);
52
+
53
+ writeValue(value: any): void {
54
+ this.value = value;
55
+ }
56
+
57
+ registerOnChange(fn: any): void {
58
+ this.onChange = fn;
59
+ }
60
+
61
+ registerOnTouched(fn: any): void {
62
+ this.onTouched = fn;
63
+ }
64
+
65
+ setDisabledState(isDisabled: boolean): void {
66
+ this.disabled = isDisabled;
67
+ }
68
+
69
+ onValueChange(val: any): void {
70
+ this.value = val;
71
+ this.onChange(val);
72
+ this.onTouched();
73
+ }
74
+
75
+ onSearchInput(event: Event): void {
76
+ this.searchTerm = (event.target as HTMLInputElement).value;
77
+ if (this.searchTimer) clearTimeout(this.searchTimer);
78
+ this.searchTimer = setTimeout(() => this.searchChange.emit(this.searchTerm), 300);
79
+ }
80
+
81
+ ngOnDestroy(): void {
82
+ if (this.searchTimer) clearTimeout(this.searchTimer);
83
+ }
84
+
85
+ getSelectedLabel(value = this.value): string {
86
+ if (this.multiple && Array.isArray(value)) {
87
+ const selectedValues = value;
88
+ const labels = this.options
89
+ .filter(opt => selectedValues.includes(opt.value))
90
+ .map(opt => opt.label);
91
+ return labels.length > 0 ? labels.join(', ') : this.placeholder;
92
+ }
93
+ const selected = this.options.find(opt => opt.value === value);
94
+ return selected ? selected.label : this.placeholder;
95
+ }
96
+ }
97
+ `,
98
+ html: `<div class="flex w-full flex-col space-y-1.5">
99
+ <label *ngIf="label" class="text-xs font-semibold text-muted-foreground">
100
+ {{ label }}<span *ngIf="required" class="text-destructive ml-0.5">*</span>
101
+ </label>
102
+
103
+ <hlm-select
104
+ *ngIf="!multiple"
105
+ class="w-full"
106
+ [value]="value"
107
+ [disabled]="disabled"
108
+ [itemToString]="itemToString"
109
+ (valueChange)="onValueChange($event)"
110
+ >
111
+ <hlm-select-trigger class="w-full">
112
+ <hlm-select-value [placeholder]="placeholder" />
113
+ </hlm-select-trigger>
114
+ <hlm-select-content *hlmSelectPortal>
115
+ <ng-container *ngTemplateOutlet="lookupSearch"></ng-container>
116
+ <hlm-select-group>
117
+ <hlm-select-item *ngIf="placeholder" [value]="null">{{ placeholder }}</hlm-select-item>
118
+ <hlm-select-item *ngFor="let opt of options" [value]="opt.value">{{ opt.label }}</hlm-select-item>
119
+ </hlm-select-group>
120
+ <ng-container *ngTemplateOutlet="lookupFooter"></ng-container>
121
+ </hlm-select-content>
122
+ </hlm-select>
123
+
124
+ <hlm-select-multiple
125
+ *ngIf="multiple"
126
+ class="w-full"
127
+ [value]="value || []"
128
+ [disabled]="disabled"
129
+ [itemToString]="itemToString"
130
+ (valueChange)="onValueChange($event)"
131
+ >
132
+ <hlm-select-trigger class="w-full">
133
+ <span class="truncate text-left">{{ getSelectedLabel() }}</span>
134
+ </hlm-select-trigger>
135
+ <hlm-select-content *hlmSelectPortal>
136
+ <ng-container *ngTemplateOutlet="lookupSearch"></ng-container>
137
+ <hlm-select-group>
138
+ <hlm-select-item *ngFor="let opt of options" [value]="opt.value">{{ opt.label }}</hlm-select-item>
139
+ </hlm-select-group>
140
+ <ng-container *ngTemplateOutlet="lookupFooter"></ng-container>
141
+ </hlm-select-content>
142
+ </hlm-select-multiple>
143
+
144
+ <ng-template #lookupSearch>
145
+ <div *ngIf="searchable" class="border-b border-border p-2">
146
+ <input
147
+ hlmInput
148
+ type="search"
149
+ class="h-8 w-full"
150
+ placeholder="Buscar..."
151
+ [value]="searchTerm"
152
+ (input)="onSearchInput($event)"
153
+ (keydown)="$event.stopPropagation()"
154
+ (click)="$event.stopPropagation()"
155
+ />
156
+ </div>
157
+ </ng-template>
158
+
159
+ <ng-template #lookupFooter>
160
+ <div *ngIf="loading" class="border-t border-border px-3 py-2 text-center text-xs text-muted-foreground">Carregando...</div>
161
+ <button
162
+ *ngIf="hasMore && !loading"
163
+ type="button"
164
+ hlmBtn
165
+ variant="ghost"
166
+ class="w-full border-t border-border"
167
+ (click)="$event.stopPropagation(); loadMore.emit()"
168
+ >
169
+ Carregar mais
170
+ </button>
171
+ </ng-template>
172
+ </div>
173
+ `
174
+ };
175
+ }
176
+ // 5. Template do devkit-table
@@ -0,0 +1,5 @@
1
+ export declare function devkitSimpleListTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitSimpleListTemplate = devkitSimpleListTemplate;
4
+ function devkitSimpleListTemplate() {
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-simple-list',
18
+ standalone: true,
19
+ imports: [CommonModule, HlmCardImports],
20
+ templateUrl: './simple-list.component.html',
21
+ styleUrls: ['./simple-list.component.css']
22
+ })
23
+ export class DevkitSimpleListComponent {
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
+ getTitleColKey(): string {
43
+ if (this.columns.some(c => c.key === 'name')) return 'name';
44
+ if (this.columns.some(c => c.key === 'title')) return 'title';
45
+ if (this.columns.some(c => c.key === 'label')) return 'label';
46
+ const nonIdCol = this.columns.find(c => c.key !== 'id' && c.key !== 'actions');
47
+ return nonIdCol ? nonIdCol.key : '';
48
+ }
49
+
50
+ getTitle(item: any): string {
51
+ const key = this.getTitleColKey();
52
+ return key ? this.getCellValue(item, key) : '';
53
+ }
54
+
55
+ isTitleCol(key: string): boolean {
56
+ return key === this.getTitleColKey();
57
+ }
58
+ }
59
+ `,
60
+ html: `<div hlmCard class="overflow-hidden py-0 gap-0">
61
+ <div *ngFor="let item of items; let index = index" (click)="rowClick.emit(item)" class="flex items-center justify-between border-b border-border p-4 transition-colors last:border-b-0 hover:bg-muted/50 cursor-pointer">
62
+ <div class="flex items-center space-x-4">
63
+ <span class="text-sm font-semibold text-muted-foreground">#{{ item.id }}</span>
64
+ <div class="flex flex-col">
65
+ <span class="text-base font-medium text-card-foreground">{{ getTitle(item) }}</span>
66
+ <div class="flex flex-wrap gap-x-4 gap-y-1 mt-1 text-xs text-muted-foreground">
67
+ <div *ngFor="let col of columns" [class.hidden]="col.key === 'id' || col.key === 'actions' || isTitleCol(col.key)" class="flex space-x-1">
68
+ <span class="font-medium">{{ col.label }}:</span>
69
+ <span>{{ getCellValue(item, col.key) }}</span>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ <div *ngIf="customTemplates && customTemplates['actions']" class="flex space-x-2">
75
+ <ng-container *ngTemplateOutlet="customTemplates['actions']; context: { $implicit: item, index: index }"></ng-container>
76
+ </div>
77
+ </div>
78
+ <div *ngIf="items.length === 0" class="text-center py-10 text-sm text-muted-foreground">
79
+ Nenhum registro encontrado.
80
+ </div>
81
+ </div>
82
+ `,
83
+ css: `:host {
84
+ display: block;
85
+ }
86
+ `
87
+ };
88
+ }
89
+ // 9. Template do devkit-dialog
@@ -0,0 +1,5 @@
1
+ export declare function devkitTableTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitTableTemplate = devkitTableTemplate;
4
+ function devkitTableTemplate() {
5
+ return {
6
+ ts: `import { Component, Input, Output, EventEmitter, TemplateRef } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { HlmTableImports } from '@spartan-ng/helm/table';
9
+ import { HlmCardImports } from '@spartan-ng/helm/card';
10
+ import { NgIconComponent } from '@ng-icons/core';
11
+
12
+ export interface ITableColumn {
13
+ key: string;
14
+ label: string;
15
+ sortable?: boolean;
16
+ }
17
+
18
+ @Component({
19
+ selector: 'devkit-table',
20
+ standalone: true,
21
+ imports: [CommonModule, HlmTableImports, HlmCardImports, NgIconComponent],
22
+ templateUrl: './table.component.html',
23
+ styleUrls: ['./table.component.css']
24
+ })
25
+ export class DevkitTableComponent {
26
+ @Input() columns: ITableColumn[] = [];
27
+ @Input() items: any[] = [];
28
+ @Input() currentSort = '';
29
+ @Input() currentDirection: 'asc' | 'desc' | 'ASC' | 'DESC' = 'ASC';
30
+ @Input() striped = false;
31
+ @Input() customTemplates?: { [columnKey: string]: TemplateRef<any> };
32
+
33
+ @Output() sortChange = new EventEmitter<{ sort: string; direction: 'ASC' | 'DESC' }>();
34
+ @Output() rowClick = new EventEmitter<any>();
35
+
36
+ getCellValue(item: any, key: string): any {
37
+ if (!key) return '';
38
+ if (key.includes('.')) {
39
+ const value = key.split('.').reduce((acc, part) => {
40
+ if (Array.isArray(acc)) return acc.map(entry => entry?.[part]).filter(Boolean);
41
+ return acc && acc[part];
42
+ }, item);
43
+ return Array.isArray(value) ? value.join(', ') : value || '';
44
+ }
45
+ return item[key] !== undefined ? item[key] : '';
46
+ }
47
+
48
+ sort(col: ITableColumn): void {
49
+ if (!col.sortable) return;
50
+ const direction = this.currentSort === col.key && (this.currentDirection === 'ASC' || this.currentDirection === 'asc') ? 'DESC' : 'ASC';
51
+ this.sortChange.emit({ sort: col.key, direction });
52
+ }
53
+ }
54
+ `,
55
+ html: `<div hlmCard class="w-full overflow-hidden py-0 gap-0">
56
+ <div hlmTableContainer class="w-full overflow-x-auto">
57
+ <table hlmTable class="w-full">
58
+ <thead hlmTHead>
59
+ <tr hlmTr class="bg-muted/40">
60
+ <th
61
+ hlmTh
62
+ *ngFor="let col of columns"
63
+ (click)="sort(col)"
64
+ [class.cursor-pointer]="col.sortable"
65
+ class="h-12 px-4 text-left align-middle font-semibold text-muted-foreground text-xs uppercase tracking-wider select-none transition-colors"
66
+ >
67
+ <div class="flex items-center space-x-1">
68
+ <span>{{ col.label }}</span>
69
+ <ng-icon
70
+ *ngIf="col.sortable && currentSort === col.key"
71
+ [name]="(currentDirection === 'desc' || currentDirection === 'DESC') ? 'lucideChevronDown' : 'lucideChevronUp'"
72
+ class="size-3 text-muted-foreground"
73
+ ></ng-icon>
74
+ </div>
75
+ </th>
76
+ </tr>
77
+ </thead>
78
+ <tbody hlmTBody>
79
+ <tr
80
+ hlmTr
81
+ *ngFor="let item of items; let index = index"
82
+ class="transition-colors hover:bg-muted/50 cursor-pointer"
83
+ [class.bg-muted/30]="striped && index % 2 !== 0"
84
+ (click)="rowClick.emit(item)"
85
+ >
86
+ <td hlmTd *ngFor="let col of columns" class="p-4 align-middle text-sm text-card-foreground">
87
+ <ng-container *ngIf="customTemplates && customTemplates[col.key]; else defaultCell">
88
+ <ng-container *ngTemplateOutlet="customTemplates[col.key]; context: { $implicit: item, index: index }"></ng-container>
89
+ </ng-container>
90
+ <ng-template #defaultCell>
91
+ {{ getCellValue(item, col.key) }}
92
+ </ng-template>
93
+ </td>
94
+ </tr>
95
+ <tr hlmTr *ngIf="items.length === 0">
96
+ <td hlmTd [attr.colspan]="columns.length" class="text-center py-10 text-sm text-muted-foreground">
97
+ Nenhum registro encontrado.
98
+ </td>
99
+ </tr>
100
+ </tbody>
101
+ </table>
102
+ </div>
103
+ </div>
104
+ `,
105
+ css: `:host {
106
+ display: block;
107
+ width: 100%;
108
+ }
109
+ `
110
+ };
111
+ }
112
+ // 6. Template do devkit-filter
@@ -0,0 +1,9 @@
1
+ export * from './theme-css.template';
2
+ export * from './readme.template';
3
+ export * from './components';
4
+ export * from './layout';
5
+ export * from './spartan';
6
+ export * from './playground.template';
7
+ export * from './shared/theme-service.template';
8
+ export * from './shared/profile-service.template';
9
+ export * from './shared/profile-component.template';
@@ -0,0 +1,25 @@
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("./theme-css.template"), exports);
18
+ __exportStar(require("./readme.template"), exports);
19
+ __exportStar(require("./components"), exports);
20
+ __exportStar(require("./layout"), exports);
21
+ __exportStar(require("./spartan"), exports);
22
+ __exportStar(require("./playground.template"), exports);
23
+ __exportStar(require("./shared/theme-service.template"), exports);
24
+ __exportStar(require("./shared/profile-service.template"), exports);
25
+ __exportStar(require("./shared/profile-component.template"), exports);
@@ -0,0 +1,5 @@
1
+ export declare function devkitHeaderTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitHeaderTemplate = devkitHeaderTemplate;
4
+ function devkitHeaderTemplate() {
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
+ import { HlmInput } from '@spartan-ng/helm/input';
10
+ import { NgIconComponent } from '@ng-icons/core';
11
+
12
+ export interface IUserProfile {
13
+ name: string;
14
+ avatar?: string;
15
+ role?: string;
16
+ }
17
+
18
+ @Component({
19
+ selector: 'devkit-header',
20
+ standalone: true,
21
+ imports: [CommonModule, HlmButton, HlmInput, NgIconComponent],
22
+ templateUrl: './header.component.html',
23
+ styleUrls: ['./header.component.css']
24
+ })
25
+ export class DevkitHeaderComponent {
26
+ @Input() showSearch = true;
27
+ @Input() showNotifications = true;
28
+ @Input() user: IUserProfile | null = null;
29
+ @Input() isSidebarCollapsed = false;
30
+ @Input() isDarkMode = false;
31
+
32
+ @Output() toggleSidebar = new EventEmitter<void>();
33
+ @Output() logout = new EventEmitter<void>();
34
+ @Output() toggleTheme = new EventEmitter<void>();
35
+ @Output() openProfile = new EventEmitter<void>();
36
+
37
+ isProfileDropdownOpen = false;
38
+
39
+ toggleProfileDropdown(): void {
40
+ this.isProfileDropdownOpen = !this.isProfileDropdownOpen;
41
+ }
42
+
43
+ onLogoutClick(): void {
44
+ this.isProfileDropdownOpen = false;
45
+ this.logout.emit();
46
+ }
47
+
48
+ onOpenProfile(): void {
49
+ this.isProfileDropdownOpen = false;
50
+ this.openProfile.emit();
51
+ }
52
+
53
+ onToggleTheme(): void {
54
+ this.toggleTheme.emit();
55
+ }
56
+ }
57
+ `,
58
+ html: `<header class="dt-header">
59
+ <div class="flex items-center space-x-4">
60
+ <!-- Botão de Toggle da Sidebar -->
61
+ <button hlmBtn variant="ghost" size="icon" (click)="toggleSidebar.emit()" class="dt-header-action" title="Menu">
62
+ <ng-icon name="lucideMenu" class="size-5"></ng-icon>
63
+ </button>
64
+
65
+ <!-- Busca Global -->
66
+ <div *ngIf="showSearch" class="relative hidden md:block">
67
+ <input hlmInput type="text" placeholder="Buscar..." class="" />
68
+ </div>
69
+ </div>
70
+
71
+ <div class="flex items-center space-x-3">
72
+
73
+ <!-- Toggle Dark / Light Mode -->
74
+ <button
75
+ hlmBtn
76
+ variant="ghost"
77
+ size="icon"
78
+ class="dt-header-action"
79
+ [title]="isDarkMode ? 'Mudar para modo claro' : 'Mudar para modo escuro'"
80
+ (click)="onToggleTheme()"
81
+ >
82
+ <ng-icon *ngIf="isDarkMode" name="lucideSun" class="size-5"></ng-icon>
83
+ <ng-icon *ngIf="!isDarkMode" name="lucideMoon" class="size-5"></ng-icon>
84
+ </button>
85
+
86
+ <!-- Notificações -->
87
+ <button *ngIf="showNotifications" hlmBtn variant="ghost" size="icon" class="dt-header-action relative" title="Notificações">
88
+ <ng-icon name="lucideBell" class="size-5"></ng-icon>
89
+ <span class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full"></span>
90
+ </button>
91
+
92
+ <!-- Linha Divisora -->
93
+ <div class="h-6 w-px bg-border"></div>
94
+
95
+ <!-- Perfil do Usuário -->
96
+ <div *ngIf="user" class="relative">
97
+ <button hlmBtn variant="ghost" (click)="toggleProfileDropdown()" class="flex items-center space-x-2 focus:outline-none py-1.5 px-2.5 rounded-md hover:bg-muted transition-colors">
98
+ <img *ngIf="user.avatar; else avatarFallback" [src]="user.avatar" [alt]="user.name" class="w-8 h-8 rounded-full object-cover border border-border" />
99
+ <ng-template #avatarFallback>
100
+ <div class="w-8 h-8 rounded-full flex items-center justify-center font-bold text-xs bg-primary text-primary-foreground">
101
+ {{ user.name.slice(0, 2).toUpperCase() }}
102
+ </div>
103
+ </ng-template>
104
+ <div class="hidden md:flex flex-col text-left">
105
+ <span class="text-sm font-semibold leading-none text-foreground">{{ user.name }}</span>
106
+ <span *ngIf="user.role" class="text-[10px] font-medium leading-none mt-1 text-muted-foreground">{{ user.role }}</span>
107
+ </div>
108
+ </button>
109
+
110
+ <!-- Dropdown -->
111
+ <div *ngIf="isProfileDropdownOpen" class="dt-header-dropdown">
112
+ <div class="px-4 py-3 border-b border-border">
113
+ <p class="text-sm font-bold text-foreground">{{ user.name }}</p>
114
+ <p *ngIf="user.role" class="text-xs text-muted-foreground mt-0.5">{{ user.role }}</p>
115
+ </div>
116
+ <button hlmBtn variant="ghost" (click)="onOpenProfile()" class="dt-header-dropdown-item">
117
+ <ng-icon name="lucideUser" class="size-4 mr-2"></ng-icon>
118
+ Editar Perfil
119
+ </button>
120
+ <div class="border-t border-border mx-2"></div>
121
+ <button hlmBtn variant="ghost" (click)="onLogoutClick()" class="dt-header-dropdown-item dt-header-dropdown-item--danger">
122
+ <ng-icon name="lucideLogOut" class="size-4 mr-2"></ng-icon>
123
+ Sair / Logout
124
+ </button>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ </header>
129
+ `,
130
+ css: `:host {
131
+ display: block;
132
+ width: 100%;
133
+ }
134
+
135
+ .dt-header {
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ height: 64px;
140
+ padding: 0 24px;
141
+ background-color: var(--card);
142
+ color: var(--card-foreground);
143
+ border-bottom: 1px solid var(--border);
144
+ box-sizing: border-box;
145
+ }
146
+
147
+ .dt-header-action {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ width: 36px;
152
+ height: 36px;
153
+ border-radius: var(--radius);
154
+ color: var(--foreground);
155
+ background: transparent;
156
+ border: none;
157
+ cursor: pointer;
158
+ transition: background-color 0.15s ease-in-out;
159
+ }
160
+
161
+ .dt-header-action:hover {
162
+ background-color: var(--muted);
163
+ }
164
+
165
+ .dt-header-search {
166
+ width: 240px;
167
+ background-color: var(--background);
168
+ color: var(--foreground);
169
+ border: 1px solid var(--input);
170
+ border-radius: 9999px;
171
+ padding: 8px 16px;
172
+ font-size: 13px;
173
+ outline: none;
174
+ font-family: var(--font-family);
175
+ transition: all 0.15s ease;
176
+ }
177
+
178
+ .dt-header-search:focus {
179
+ border-color: var(--ring);
180
+ width: 280px;
181
+ }
182
+
183
+ .dt-header-dropdown {
184
+ position: absolute;
185
+ right: 0;
186
+ top: calc(100% + 8px);
187
+ width: 220px;
188
+ background-color: var(--popover);
189
+ color: var(--popover-foreground);
190
+ border: 1px solid var(--border);
191
+ border-radius: var(--radius);
192
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
193
+ z-index: 100;
194
+ display: flex;
195
+ flex-direction: column;
196
+ padding: 4px 0;
197
+ font-family: var(--font-family);
198
+ }
199
+
200
+ .dt-header-dropdown-item {
201
+ width: 100%;
202
+ padding: 10px 16px;
203
+ background: transparent;
204
+ border: none;
205
+ text-align: left;
206
+ font-size: 13px;
207
+ color: var(--popover-foreground);
208
+ cursor: pointer;
209
+ font-family: var(--font-family);
210
+ transition: background-color 0.15s ease-in-out;
211
+ display: flex;
212
+ align-items: center;
213
+ }
214
+
215
+ .dt-header-dropdown-item:hover {
216
+ background-color: var(--muted);
217
+ }
218
+
219
+ .dt-header-dropdown-item--danger {
220
+ color: var(--destructive);
221
+ }
222
+
223
+ .dt-header-dropdown-item--danger:hover {
224
+ background-color: color-mix(in srgb, var(--destructive) 10%, transparent);
225
+ color: var(--destructive);
226
+ }
227
+
228
+ @media (max-width: 768px) {
229
+ .dt-header {
230
+ padding: 0 16px;
231
+ }
232
+ }
233
+ `
234
+ };
235
+ }
236
+ // 13. Template do MainLayoutComponent
@@ -0,0 +1,4 @@
1
+ export * from './shell.template';
2
+ export * from './sidebar.template';
3
+ export * from './header.template';
4
+ export * from './main-layout.template';